Pular para o conteúdo
Fynx
Business Intelligence11 min de leitura

Power Query: como usar query folding para acelerar a carga

Aprenda a usar query folding no Power Query para acelerar a carga: o que é, como verificar com View Native Query e quais etapas quebram o folding.

F
Fynx

Sua carga demora minutos e você culpa a internet, mas o problema está no Power Query

Se o refresh do seu relatório leva minutos para atualizar poucas centenas de milhares de linhas, a rede quase nunca é a culpada. Na maioria dos casos o motivo é que o Power Query está baixando a tabela inteira para dentro da sua máquina e só depois aplicando os filtros, as agregações e os cruzamentos. Existe uma forma muito mais eficiente de trabalhar, e ela tem nome: query folding. Saber usar query folding para acelerar a carga é uma das habilidades que mais separa um relatório que trava de um que atualiza em segundos, e é isso que eu vou destrinchar aqui.

Este artigo é direto e prático. Vou explicar o que é query folding, como verificar se ele está ativo usando o View Native Query, quais transformações costumam quebrar o folding e como reordenar as etapas para preservá-lo. Com exemplos que você reconhece do seu dia a dia. É o tipo de otimização que a gente aplica nos projetos de Power BI e de engenharia de dados da Fynx todos os dias.

Query folding é o Power Query terceirizando o trabalho pesado para a fonte

Toda vez que você aplica uma etapa no Editor do Power Query (filtrar linhas, remover colunas, agrupar, renomear), o Power Query gera uma instrução na linguagem M. Quando a fonte é um banco de dados relacional, o Power Query tenta traduzir essas etapas em uma única consulta nativa, normalmente um comando SQL, e envia essa consulta para o banco executar. Esse processo de traduzir os passos do M em uma consulta da fonte é o query folding.

A vantagem é enorme. Em vez de puxar 20 milhões de linhas para a sua memória e depois filtrar as 3 mil que interessam, o Power Query manda o banco filtrar e devolver apenas as 3 mil. O trabalho pesado acontece no servidor, que é otimizado para isso, tem índices e processa em paralelo. O que trafega pela rede é só o resultado.

Sem folding, o comportamento se inverte. O Power Query baixa tudo e faz cada transformação no motor local, chamado motor Mashup. É por isso que a mesma consulta pode levar 8 segundos em um cenário e 8 minutos em outro. A diferença raramente é o volume de dados, é quem está fazendo o trabalho.

Onde o folding funciona e onde ele nem começa

O folding depende da fonte conseguir receber e executar uma consulta. Isso limita bastante onde ele acontece:

Fonte de dadosSuporte a query folding
SQL Server, Azure SQL, PostgreSQL, Oracle, MySQLSim, é o cenário ideal
Dataverse e OData bem construídosParcial, depende das operações
SharePoint List (via conector)Limitado
Arquivos Excel, CSV, TXT, JSONNão, arquivo não executa consulta
Pasta de arquivos combinadosNão
Web scraping e APIs sem ODataGeralmente não

A conclusão prática é dura, mas honesta: se a sua fonte é um arquivo em pasta ou um CSV, não existe folding para preservar. Nesses casos o caminho costuma ser levar esses dados para um banco antes, exatamente o tipo de arquitetura que tratamos em engenharia de dados.

O View Native Query mostra o SQL que o Power Query realmente enviou

Você não precisa adivinhar se o folding está ativo. O Power Query tem uma janela que mostra a consulta nativa gerada. O caminho é este:

  1. Abra o Editor do Power Query (Transformar dados).
  2. Na lista de etapas aplicadas, à direita, clique com o botão direito sobre uma etapa.
  3. Se a opção Exibir consulta nativa (View Native Query) estiver habilitada e você conseguir clicar, aquela etapa está dobrando. O Power Query abre uma janela com o SQL que seria enviado à fonte.
  4. Se a opção estiver acinzentada (desabilitada), o folding parou naquela etapa ou antes dela.

Esse teste é o seu melhor amigo. A técnica que eu mais uso é subir etapa por etapa, da última para a primeira, verificando em qual delas o View Native Query deixa de estar disponível. Aquela é a etapa que quebrou o folding, e tudo o que vem depois dela roda localmente.

Um detalhe importante: o View Native Query mostra o SQL até a etapa selecionada. Se você clicar na última etapa e ele exibir um SELECT completo, com WHERE e GROUP BY, a consulta inteira está dobrando. É o cenário que você quer.

// Exemplo de etapas que DOBRAM inteiras em um banco SQL
let
    Fonte = Sql.Database("servidor", "Vendas"),
    Pedidos = Fonte{[Schema="dbo", Item="Pedidos"]}[Data],
    FiltraAno = Table.SelectRows(Pedidos, each [DataPedido] >= #date(2025,1,1)),
    RemoveColunas = Table.SelectColumns(FiltraAno, {"ClienteID","Valor","DataPedido"}),
    Agrupado = Table.Group(RemoveColunas, {"ClienteID"}, {{"Total", each List.Sum([Valor]), type number}})
in
    Agrupado

No exemplo acima, com uma fonte SQL, o filtro por ano, a seleção de colunas e o agrupamento se traduzem em um único SELECT com WHERE e GROUP BY. O banco faz tudo e devolve o resultado já resumido. É o oposto de baixar milhões de linhas para agrupar na memória.

Algumas transformações quebram o folding, e é bom conhecê-las de cor

Nem toda operação tem equivalente em SQL, e nem todo conector consegue traduzir tudo. Quando o Power Query encontra uma etapa que não sabe converter, ele para de dobrar dali em diante e passa a processar localmente. O problema não é a etapa em si, é que ela contamina todas as etapas seguintes.

Segue um resumo do que costuma preservar e do que costuma quebrar o folding em fontes que suportam o recurso. Trate como orientação geral, porque o comportamento varia entre conectores e versões:

Preserva o folding (bom)Quebra o folding (cuidado)
Filtrar linhas (Table.SelectRows)Adicionar coluna de índice (Table.AddIndexColumn)
Remover ou selecionar colunasMesclar consultas de fontes diferentes
Renomear colunasCertas funções de texto sem equivalente SQL
Agrupar e agregar (soma, contagem)Table.Buffer, que força o carregamento em memória
Mesclar tabelas da mesma fonteColunas personalizadas com lógica M complexa
Filtrar por data e por valoresAlterar tipo para um tipo sem correspondência
Ordenar (com ressalvas)Extrair dados de um arquivo ou API no meio do fluxo

O caso mais clássico é a coluna de índice. SQL não tem um conceito nativo de número de linha sequencial que o Power Query consiga sempre traduzir, então adicionar índice quase sempre encerra o folding. Se você adiciona o índice como uma das primeiras etapas, condena todo o resto da consulta a rodar localmente. Outro caso comum são transformações de texto mais específicas, como certos usos de limpeza, capitalização ou extração de trechos que não têm função SQL direta equivalente no dialeto da fonte.

Regra de bolso: se você precisa de uma etapa que quebra o folding, deixe-a o mais tarde possível na sequência, para que tudo o que puder ser empurrado para o banco continue sendo empurrado.

A ordem das etapas decide o quanto o banco trabalha por você

Aqui está o ponto que separa quem só monta a consulta de quem otimiza de verdade. O Power Query avalia as etapas na ordem em que elas aparecem. O folding sobrevive enquanto cada etapa consegue ser traduzida, e ele morre na primeira que não consegue. Depois disso, não volta.

Isso tem duas consequências práticas. A primeira: coloque as etapas que reduzem volume o mais cedo possível. Filtrar linhas e remover colunas logo no começo faz o banco devolver menos dados. A segunda: empurre as etapas que quebram o folding para o fim, para não desligar o recurso antes da hora.

Veja a diferença. Na versão ruim, o índice entra cedo e derruba tudo:

// RUIM: o índice quebra o folding logo no início
let
    Fonte = Sql.Database("servidor", "Vendas"),
    Pedidos = Fonte{[Schema="dbo", Item="Pedidos"]}[Data],
    AdicionaIndice = Table.AddIndexColumn(Pedidos, "Indice", 1, 1),  // folding para aqui
    FiltraAno = Table.SelectRows(AdicionaIndice, each [DataPedido] >= #date(2025,1,1)),  // roda local
    RemoveColunas = Table.SelectColumns(FiltraAno, {"Indice","ClienteID","Valor"})  // roda local
in
    RemoveColunas

Nessa ordem, o Power Query baixa a tabela inteira para adicionar o índice, e só depois filtra e remove colunas na memória local. Todo o volume passou pela sua máquina à toa.

Agora a versão boa, com o índice no fim:

// BOM: filtra e reduz primeiro, quebra o folding só no final
let
    Fonte = Sql.Database("servidor", "Vendas"),
    Pedidos = Fonte{[Schema="dbo", Item="Pedidos"]}[Data],
    FiltraAno = Table.SelectRows(Pedidos, each [DataPedido] >= #date(2025,1,1)),  // dobra
    RemoveColunas = Table.SelectColumns(FiltraAno, {"ClienteID","Valor","DataPedido"}),  // dobra
    AdicionaIndice = Table.AddIndexColumn(RemoveColunas, "Indice", 1, 1)  // quebra aqui, mas já veio pouca coisa
in
    AdicionaIndice

Nessa segunda versão, o banco recebe um SELECT com filtro e projeção de colunas, devolve apenas o subconjunto que interessa, e o índice é aplicado localmente sobre um volume já reduzido. Mesmo resultado final, tempo de carga muito menor.

Um roteiro de ordenação que funciona

Como ponto de partida, organize as etapas nesta ordem de prioridade:

  1. Conexão com a fonte.
  2. Filtros de linha que eliminam muito volume (datas, status, empresa).
  3. Remoção de colunas que você não vai usar.
  4. Agrupamentos e agregações que a fonte consiga executar.
  5. Mesclagens com outras tabelas da mesma fonte.
  6. Por último, e só quando inevitável, as etapas que quebram o folding (índice, colunas personalizadas complexas, transformações de texto sem equivalente).

Esse roteiro não é dogma, mas resolve a maioria dos casos. E ele conversa direto com boas práticas de modelagem: quanto mais enxuta e bem tipada a tabela chega ao modelo, melhor. Se você quer ir além na parte de modelo e medidas, vale ler o nosso guia de boas práticas de modelagem e DAX.

Query folding não resolve tudo, e é honesto dizer isso

Folding é poderoso, mas não é mágica. Ele depende de a fonte suportar o recurso, e muitos cenários corporativos misturam bancos, arquivos e APIs no mesmo relatório. Quando você precisa cruzar uma tabela do SQL Server com uma planilha do financeiro, a etapa de mesclagem entre fontes diferentes tende a quebrar o folding, e não há reordenação que salve.

Nesses casos, a resposta não está no Power Query, está na arquitetura de dados. Levar os arquivos para uma camada intermediária, um banco ou um lakehouse, e cruzar tudo já dentro da mesma fonte, devolve o folding para o jogo. É uma decisão de plataforma, não de consulta. Se a sua operação já vive esse tipo de dor, o caminho pode passar por repensar a base com engenharia de dados ou por avaliar o Microsoft Fabric, que reorganiza justamente onde o processamento acontece.

Perguntas frequentes

Como sei rapidamente se meu query folding está funcionando? Abra o Editor do Power Query, clique com o botão direito na última etapa aplicada e procure a opção Exibir consulta nativa (View Native Query). Se ela estiver disponível e mostrar um SQL completo, a consulta está dobrando. Se estiver acinzentada, o folding parou em alguma etapa anterior. Suba etapa por etapa para descobrir exatamente onde.

Arquivos Excel e CSV fazem query folding? Não. Query folding exige uma fonte capaz de receber e executar uma consulta, como um banco de dados relacional. Arquivos não executam consultas, então todas as transformações rodam localmente no motor do Power Query. Para grandes volumes vindos de arquivos, o melhor caminho é carregá-los antes em um banco ou em uma camada de armazenamento.

Adicionar uma coluna de índice sempre quebra o folding? Na prática, quase sempre. A maioria dos bancos e conectores não tem tradução direta para a numeração sequencial que o Power Query aplica. Por isso, se você realmente precisa do índice, adicione-o como uma das últimas etapas, depois de já ter filtrado e reduzido os dados o máximo possível.

Reordenar as etapas muda o resultado final da consulta? Na maioria dos casos, não muda o resultado, apenas o desempenho. Filtrar antes ou depois de remover colunas costuma gerar a mesma tabela final, mas com tempos de carga bem diferentes. Sempre confira o resultado após reordenar, porque algumas operações dependem da ordem, como agrupamentos combinados com colunas personalizadas.

Query folding acelera também o refresh no Power BI Service? Sim, e o ganho é ainda mais relevante lá. Com folding ativo, o gateway ou o serviço envia a consulta à fonte e recebe só o resultado, reduzindo o tempo de atualização agendada e o consumo de recursos. Sem folding, o mesmo refresh tende a demorar mais e a pesar sobre o gateway.

O Table.Buffer ajuda ou atrapalha o folding? Atrapalha, se o seu objetivo é preservar o folding. O Table.Buffer força o carregamento da tabela em memória naquele ponto, o que encerra a tradução para a fonte. Ele tem usos legítimos para estabilizar resultados ou evitar reavaliações, mas deve ser usado com consciência, porque desliga o folding dali para a frente.

Coloque o banco para trabalhar por você

Query folding é uma das otimizações de maior retorno e menor custo no Power Query: reorganizar etapas e verificar o View Native Query não custa licença nenhuma e pode transformar minutos de refresh em segundos. Comece testando suas consultas hoje, uma etapa de cada vez, e observe onde o folding quebra. Se a sua base é grande, mistura muitas fontes ou já dá sinais de que o Power Query não dá conta sozinho, fale com a gente e vamos desenhar a arquitetura certa para o seu caso.

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.