Pular para o conteúdo
Fynx
Power BI12 min de leitura

SUMX e iteradores em DAX: o que faz e quando usar (com exemplos)

Entenda SUMX e iteradores DAX: sintaxe, contexto de linha, armadilhas de performance e boas práticas para escrever medidas corretas e rápidas no Power BI.

F
Fynx

Sua medida de faturamento está errada e o culpado provavelmente é um SUM

Quase todo relatório de Power BI que chega para revisão tem o mesmo defeito escondido: alguém precisava multiplicar quantidade por preço unitário e criou uma coluna calculada só para depois somar com SUM. Funciona, o número aparece, ninguém questiona. Até o modelo crescer, a atualização demorar e o relatório perder memória. É aí que entender SUMX e iteradores DAX deixa de ser assunto de curso avançado e vira necessidade de quem quer entregar BI que sustenta decisão.

A confusão entre SUM e SUMX é a primeira grande virada de chave em DAX. Elas parecem primas, mas resolvem problemas diferentes e se comportam de formas diferentes por baixo do capô. Vou destrinchar o que são as funções iteradoras (as funções X), quando você precisa delas, onde elas te derrubam em performance e como escrever medidas corretas.

SUMX e iteradores DAX percorrem a tabela linha a linha

DAX tem dois grandes grupos de funções de agregação. O primeiro é o das agregações simples: SUM, AVERAGE, MIN, MAX, COUNT. Elas recebem uma coluna e devolvem um valor. O segundo é o dos iteradores, as funções terminadas em X: SUMX, AVERAGEX, MINX, MAXX, COUNTX, RANKX, CONCATENATEX e outras.

A diferença é como cada grupo trabalha. SUM(Vendas[Valor]) pega a coluna inteira e soma. Já SUMX faz duas coisas: percorre uma tabela linha a linha, avaliando uma expressão em cada linha, e depois soma todos os resultados. Por isso todo iterador tem a mesma assinatura de dois argumentos:

SUMX(tabela, expressão)

O primeiro argumento é a tabela percorrida e o segundo é a expressão avaliada em cada linha. O exemplo clássico é o total de faturamento quando você tem quantidade e preço separados:

Faturamento = SUMX(Vendas, Vendas[Quantidade] * Vendas[PrecoUnitario])

Aqui o motor visita cada linha da tabela Vendas, multiplica quantidade por preço unitário naquela linha e, no fim, soma tudo. É a única forma matematicamente correta de fazer isso. Um SUM(Vendas[Quantidade]) * SUM(Vendas[PrecoUnitario]) daria um número errado, porque somaria todas as quantidades, somaria todos os preços e multiplicaria os dois totais.

O que faz um iterador funcionar é o contexto de linha

Para usar iteradores sem apanhar, você precisa entender o contexto de linha. Quando SUMX percorre a tabela, em cada iteração existe uma linha "atual". Dentro da expressão, quando você escreve Vendas[Quantidade], o DAX sabe de qual linha está falando: a linha corrente da iteração. Esse é o contexto de linha, criado automaticamente por qualquer iterador.

Isso explica por que dentro de SUMX você referencia colunas diretamente, enquanto numa medida comum isso gera erro. Uma medida pura não tem contexto de linha, vive só no contexto de filtro. O iterador é o que injeta contexto de linha na expressão.

Um detalhe que derruba muita gente: dentro do contexto de linha, você pode navegar por relacionamentos com RELATED. Se a tabela Vendas tem chave para Produtos, dá para fazer:

Margem = SUMX(Vendas, Vendas[Quantidade] * (Vendas[PrecoUnitario] - RELATED(Produtos[Custo])))

O RELATED traz o custo da tabela de produtos para a linha atual de vendas. Sem contexto de linha, ele não saberia qual produto buscar, e por isso só funciona em iteradores ou colunas calculadas.

Quando usar iterador e quando o SUM simples basta

A regra é curta: use agregação simples sempre que puder, e iterador só quando a matemática exigir uma operação linha a linha antes de agregar. Não saia trocando todo SUM por SUMX achando que fica mais sofisticado. Fica só mais lento sem motivo.

A tabela abaixo resume os cenários mais frequentes em projeto.

CenárioUsePor quê
Somar uma coluna que já existe prontaSUMNão há cálculo por linha, o VertiPaq resolve direto
Quantidade x preço unitário em cada linhaSUMXA multiplicação precisa acontecer linha a linha
Média ponderadaSUMX / AVERAGEXO peso muda o cálculo em cada linha
Maior venda individual de um clienteMAXXPrecisa avaliar uma expressão por linha antes do máximo
Contar linhas que atendem a uma condição calculadaCOUNTX ou SUMX com IFA condição depende de cálculo por linha
Ranking de produtos por faturamentoRANKXOrdena resultados de uma expressão avaliada por item

Em nenhum desses casos o iterador é escolha estética. Ele entra porque a operação exige avaliação por linha. Se você tem uma coluna Valor já materializada e só precisa somá-la, SUM(Vendas[Valor]) é a resposta certa.

Há um caso intermediário: e a coluna calculada? Você poderia criar Valor = Vendas[Quantidade] * Vendas[PrecoUnitario] e usar SUM. Funciona, mas tem custo. A coluna ocupa memória, é materializada na atualização e piora a compressão. SUMX calcula na consulta e não guarda nada. Prefira o SUMX na medida. A exceção é quando a mesma expressão por linha é reaproveitada em dezenas de medidas e o volume de linhas é moderado. Essa decisão de arquitetura discutimos a fundo em modelagem e boas práticas de DAX.

O iterador não é lento por natureza, mas ele pode ser

Existe um mito de que iterador é sempre pesado. Não é verdade. O motor de fórmulas do Power BI, junto com o VertiPaq, é capaz de otimizar muitos iteradores, transformando o SUMX em algo tão rápido quanto uma agregação simples, desde que a expressão interna seja feita de colunas da própria tabela e aritmética básica.

O problema aparece quando você quebra essa otimização, e é aí que mora a maioria dos gargalos que encontro em sustentação de BI. Alguns padrões que forçam o motor a cair no modo lento:

  • Chamar uma medida dentro da expressão do iterador. Cada linha reavalia a medida inteira, com todo o seu contexto de filtro.
  • Usar funções que não são "storage engine friendly", como certas lógicas de texto ou de tempo dentro do laço.
  • Iterar sobre uma tabela gigante quando bastaria iterar sobre uma menor já filtrada.
  • Aninhar iteradores, um SUMX dentro de outro, criando um produto cartesiano de avaliações.

Para dar dimensão do impacto, lembre como o VertiPaq guarda os dados. Ele comprime cada coluna separadamente, e a taxa de compressão depende da cardinalidade, o número de valores distintos. Uma coluna com poucos valores distintos comprime muito e é lida rápido. Uma iteração sobre colunas de baixa cardinalidade e aritmética simples voa. Uma que precisa expandir contexto de filtro linha a linha, não.

A tabela abaixo mostra padrões que eu trato como sinal de alerta em revisão de código.

Padrão no códigoRiscoAlternativa
Medida chamada dentro de SUMXAltoReescrever com colunas diretas ou variáveis
SUMX(Tabela, ...) sobre a fato inteira sem filtroMédio a altoFiltrar a tabela antes ou usar CALCULATE
SUMX aninhado em SUMXAltoRepensar a lógica, muitas vezes há caminho mais direto
Coluna calculada usada só para depois somarBaixo a médioMigrar o cálculo para dentro de SUMX na medida
FILTER desnecessário envolvendo a tabela inteiraMédioUsar filtro simples de coluna no CALCULATE

Variáveis são a ferramenta que salva iteradores complexos

Quando a expressão dentro do iterador cresce, use VAR. Além de deixar o código legível, variáveis são calculadas uma vez e reaproveitadas, evitando reavaliar a mesma subexpressão em cada passagem:

Receita Liquida = SUMX(Vendas, Vendas[Quantidade] * Vendas[PrecoUnitario] * (1 - Vendas[PercDesconto]))

Uma armadilha importante: uma variável declarada fora do iterador é avaliada no contexto de fora e fica constante durante toda a iteração. Pode ser o que você quer, ou um bug silencioso. Já uma variável declarada dentro da expressão do iterador é reavaliada a cada linha. Saber onde declarar o VAR é metade da briga.

AVERAGEX, MAXX e os outros primos do SUMX

SUMX é o mais famoso, mas a família toda segue a mesma lógica de percorrer e depois agregar. Eles resolvem perguntas de negócio que agregação simples não alcança.

  • AVERAGEX calcula a média de uma expressão por linha. Serve para média de ticket, média de itens por pedido.
  • MAXX e MINX avaliam a expressão em cada linha e devolvem o maior ou o menor resultado, como o maior pedido de um cliente.
  • COUNTX conta as linhas em que a expressão não é vazia, útil quando a condição depende de cálculo.
  • RANKX gera ranking avaliando uma expressão por item e ordenando. É a base de qualquer análise de "top N".
  • CONCATENATEX junta textos linha a linha com um separador, ótimo para rótulos dinâmicos em um cartão.

Um erro comum é achar que AVERAGEX e AVERAGE dão sempre o mesmo número. Não dão. AVERAGE(Vendas[Valor]) é a média dos valores de linha. AVERAGEX(Clientes, [Total Vendas]) é a média por cliente, granularidade diferente. Escolher a granularidade certa da tabela iterada separa a métrica correta da que engana o negócio.

Erros que eu vejo com mais frequência em projeto

Alguns tropeços se repetem em revisão. Reconhecê-los economiza horas.

O primeiro é somar totais no lugar de iterar, aquele SUM(Qtd) * SUM(Preco). Passa despercebido porque o número parece plausível com uma venda só, e explode quando há muitas.

O segundo é iterar na tabela errada. A tabela que você passa como primeiro argumento define a granularidade do resultado.

O terceiro é misturar contexto de linha e de filtro sem entender a transição de contexto. Quando você chama uma medida dentro de um iterador, o contexto de linha vira contexto de filtro. É poderoso, mas caro, e origem de muitas medidas lentas.

O quarto é o excesso de FILTER, como SUMX(FILTER(Vendas, Vendas[Regiao]="Sul"), ...) quando um filtro simples no CALCULATE resolveria melhor. FILTER também é um iterador, e envolver a tabela inteira nele tem custo.

Se você está montando a base analítica do zero, trate modelagem e performance como parte do projeto, não como remendo posterior. É o tipo de fundação que cuidamos em projetos de Power BI, e que também aparece no guia completo de Power BI para empresas.

O contexto maior: por que isso importa em Fabric e no dia a dia

DAX não mudou de natureza com a chegada do Microsoft Fabric, anunciado pela Microsoft em 2023. O motor VertiPaq continua sendo o coração dos modelos de importação, e no modo Direct Lake, que lê os dados diretamente do OneLake, as mesmas regras de cardinalidade e de otimização valem. A diferença é que em Fabric o consumo é medido em Capacity Units, cobradas em SKUs que vão de F2 a F2048, enquanto o Premium por capacidade tradicional usava a família P1 a P5. Nesses cenários, uma medida mal escrita não é só lentidão percebida, ela consome capacidade que você está pagando.

Isso é comum no Brasil porque a adoção de Power BI é ampla pela penetração do ecossistema Microsoft, e a Microsoft é reconhecida como Líder no Quadrante Mágico do Gartner para plataformas de Analytics e BI. Muita gente entra vindo do Excel e traz o hábito de calcular tudo em colunas, o que empurra o modelo para o caminho ineficiente. As licenças de usuário, Power BI Pro e PPU, e as faixas de preço de capacidade variam e devem ser confirmadas na fonte oficial da Microsoft, mas o princípio é estável: capacidade tem custo, e código eficiente o protege. Se o seu ambiente está em Fabric ou pensa em migrar, dá para aprofundar em o que é o Microsoft Fabric e se vale a pena.

Perguntas frequentes

Qual a diferença prática entre SUM e SUMX?

SUM soma uma coluna que já existe, em uma única operação. SUMX percorre uma tabela linha a linha, avalia uma expressão em cada linha e depois soma os resultados. Use SUM quando a coluna já está pronta e SUMX quando precisa calcular algo por linha antes de somar, como quantidade vezes preço.

SUMX é sempre mais lento que SUM?

Não. Quando a expressão interna é simples, o motor otimiza o SUMX e o desempenho fica próximo de uma agregação simples. A lentidão aparece quando você chama medidas dentro do iterador, aninha iteradores ou itera sobre tabelas enormes sem filtrar.

Posso usar RELATED dentro de SUMX?

Sim, e é um dos usos mais úteis. Como o iterador cria contexto de linha, o RELATED traz valores de tabelas relacionadas para a linha corrente. É assim que você calcula margem trazendo o custo dos produtos para o laço sobre vendas.

É melhor criar uma coluna calculada ou usar SUMX na medida?

Na maioria dos casos, prefira o SUMX na medida. A coluna calculada ocupa memória, é materializada na atualização e pode piorar a compressão. Ela só compensa quando a mesma expressão é reaproveitada em muitas medidas e o volume de linhas é controlado.

Por que minha média com AVERAGEX não bate com AVERAGE?

Porque elas medem granularidades diferentes. AVERAGE calcula a média dos valores de linha da coluna. AVERAGEX calcula a média da expressão por linha da tabela indicada, que pode ser clientes, pedidos ou produtos. Escolha a tabela iterada conforme o nível em que a média faz sentido para o negócio.

Como sei se um iterador está prejudicando a performance do relatório?

Use o Performance Analyzer do Power BI Desktop para medir o tempo de cada visual e o DAX Studio para diagnósticos mais profundos, que mostram se a consulta cai no storage engine rápido ou no formula engine lento. Medidas que chamam outras medidas dentro de iteradores são as primeiras suspeitas.

Fechamento

Iteradores não são um recurso para impressionar, são a ferramenta certa para uma classe específica de problemas: qualquer cálculo que precise acontecer linha a linha antes de agregar. Domine o contexto de linha, respeite os limites de performance e resista à tentação de trocar todo SUM por SUMX. Medida boa é a mais simples que resolve o problema.

Se a sua equipe luta com relatórios lentos, números que não batem ou um modelo que virou uma teia de colunas calculadas, isso tem conserto e geralmente começa por revisar as medidas. Fale com a gente e a gente ajuda a colocar o seu Power BI em ordem.

Quer aplicar isso na sua empresa?

A Fynx implementa BI, Power BI e Power Platform de ponta a ponta. Conte seu cenário e devolvemos um diagnóstico direto ao ponto.

Falar com um especialista

Vamos transformar seus dados em decisão?

Conte seu cenário. Devolvemos um diagnóstico e uma proposta com faixa de investimento em poucos dias úteis, sem folheto, direto ao ponto.