(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

DP-600: optimizar cardinalidade e performance de relações em modelos semânticos

João Barros 04 de October de 2026 6 min de leitura

Vou ensinar como optimizar a cardinalidade e a performance das relações num modelo semântico (Power BI / Fabric) — uma competência útil para o DP-600 e essencial para modelos escaláveis e ágeis. Saber isto ajuda a reduzir a latência de consultas, diminuir o uso de memória e a garantir resultados correctos em análises complexas, especialmente em cenários com milhões de linhas ou quando se combina Import e DirectQuery.

O que precisas de saber

Num modelo semântico, as tabelas são ligadas por relações (relationships) definidas entre colunas. A cardinalidade (one-to-one, one-to-many, many-to-one, many-to-many) e a direcção do filtro (single, both/directions) afectam tanto a lógica dos cálculos como a performance das consultas. Relações são avaliadas pelo motor VertiPaq no modo Import e passam por mecanismos de delegação no modo DirectQuery. Um desenho eficiente evita cálculos desnecessários, reduz junções e permite que o engine use compressão columnar e índices de forma eficaz.

Exemplo simples e numérico: suponhamos uma FactSales com 10 milhões de linhas e uma DimProduct com 10 000 linhas. A relação correcta é DimProduct (1) -> FactSales (many). Se DimProduct tiver duplicados ou chaves mal definidas, a mesma consulta que demora 200 ms com uma relação correcta pode passar a demorar vários segundos ou devolver resultados errados. Em modo Import, colunas inteiras e de baixa cardinalidade comprimem muito melhor do que strings longas ou GUIDs.

Como funciona na prática

Passos práticos para optimizar relações:

  1. Verificar unicidade nas tabelas de dimensão: as colunas usadas como chave (por exemplo ProductID) devem ser únicas na dimensão. Usa DISTINCTCOUNT(DimProduct[ProductID]) para validar no Power BI ou uma consulta SQL na ETL. Se existirem duplicados, cria uma surrogate key (ID inteiro sequencial) ou resolve a duplicidade na fase de preparação de dados. Numa dimensão típica de 10k linhas, a unicidade é fácil de garantir; já em dimensões de clientes com 2M de registos, é crítico.
  2. Escolher a cardinalidade correcta: define one-to-many sempre que uma dimensão descreve várias fact rows. Evita many-to-many excepto quando estritamente necessário — many-to-many frequentemente requer uma tabela bridge e aumenta o custo de cálculo. Por exemplo, uma relação many-to-many entre 100k clientes e 50k produtos pode multiplicar a carga de cálculo e aumentar o tempo de query 5x–10x se não for tratada correctamente.
  3. Definir direcção de filtro mínima: usa single direction filter por defeito. Apenas utiliza both direction quando necessário para cross-filtering em visuais específicos. Em modelos grandes, both direction pode provocar propagação de filtros custosa e ambiguidade nas rotas de filtro, elevando o custo de computação e de RAM.
  4. Normalizar chaves e tipos: assegura que as colunas de ligação têm o mesmo tipo (inteiro vs texto) e formato. Conversões implícitas em tempo de execução degradam a performance. Por exemplo, ligar uma coluna GUID (texto de 36 caracteres) a um inteiro impede compressão eficiente e aumenta o tamanho do modelo — a conversão para um ID inteiro pode reduzir o espaço ocupado em 25–50% e diminuir tempos de consulta em 30–70% em alguns cenários.
  5. Reduzir cardinalidade de fact keys: se a fact tem chaves muito largas (p.ex. GUIDs string ou chaves compostas), considera mapear para inteiros sequenciais para melhorar compressão e indexabilidade. Colunas com alta cardinalidade (milhões de valores distintos) reduzem a eficácia da compressão columnar do VertiPaq.
  6. Evitar relações cruzadas e ambíguas: mantém um esquema claro (star schema). Relações em cadeia ou cruzadas criam caminhos alternativos de filtro que aumentam o custo de cálculo e podem causar resultados inesperados. Mantém uma star schema com dimensões centralizadas para fact tables sempre que possível.
-- Pseudocódigo DAX para testar unicidade
EVALUATE
SUMMARIZE(
  DimProduct,
  DimProduct[ProductID],
  "CountRows", COUNTROWS(FILTER(DimProduct, DimProduct[ProductID]=EARLIER(DimProduct[ProductID])))
)
-- Procura ProductID com CountRows > 1

Em ambientes com DirectQuery, minimizar junções e delegar agregações ao sistema fonte (por exemplo SQL do data warehouse) é crucial para manter latências baixas. Para modo Import, optimizar cardinalidade e tipos ajuda o engine a usar compressão columnar e reduzir memória, além de acelerar cálculos DAX.

Erros comuns

  • Usar both-direction por defeito: leva a performance degradada e dificuldade em explicar o comportamento dos filtros. Num relatório com 15 visuais, both-direction pode duplicar o tempo total de processamento porque os filtros propagam-se em múltiplos caminhos.
  • Ignorar unicidade: estabelecer uma relação one-to-many quando a dimensão não é única causa resultados incorrectos e confusão nos cálculos. Deteta isto com testes de unicidade e validação automática na ETL.
  • Misturar tipos nas colunas de relação: chaves de texto vs inteiro forçam conversões e impedem optimizações do motor. Isto pode não só aumentar latência, como provocar falhas em certas funções DAX que esperam tipos específicos.
  • Modelos snowflake quando não necessário: normalizar demasiado pode obrigar a múltiplas junções e penalizar a performance. Prefere star schema para reporting.

Como praticar

Pratica com datasets reais e sintéticos: cria uma Fact grande (por exemplo 5–20 milhões de linhas) e várias Dimensions (5k–50k linhas); testa diferentes configurações de cardinalidade e direcção de filtro; mede tempo de refresh e tempo de queries no Power BI Desktop ou no ambiente Fabric. Usa o Performance Analyzer no Power BI para captar a duração de queries DAX por visual. Ferramentas adicionais como DAX Studio e VertiPaq Analyzer ajudam a analisar planos e compressão.

Exercício sugerido: importa uma FactSales de 10M linhas com ProductID como GUID e mede o tamanho do ficheiro e o tempo de consulta; depois transforma o GUID em inteiro sequencial, reinstala a relação one-to-many e regista a redução de tamanho do modelo e a melhoria de latência. Anota números (MB, ms) para comparar.

Para preparação formal, utiliza o Practice Assessment OFICIAL gratuito da Microsoft e a study guide oficial (também gratuita). Estes recursos ajudam-te a validar conhecimentos nas áreas medidas pelo DP-600 sem recorrer a material proibido.

Em resumo

  • Define correctamente a cardinalidade (one-to-many quando a dimensão é única) para garantir resultados correctos e melhor performance.
  • Usa a direcção de filtro mínima (single) e evita both-direction excepto quando necessário.
  • Assegura unicidade e compatibilidade de tipos nas colunas de ligação para evitar conversões e erros.
  • Testa a performance com dados reais e com o Performance Analyzer; usa DAX Studio/VertiPaq Analyzer para diagnóstico; e consulta os recursos oficiais da Microsoft (Practice Assessment e study guide gratuitos) para estruturar o teu estudo.