Cos’è il query folding

Il query folding è la capacità di Power Query di tradurre gli step di trasformazione che scrivi nell’editor grafico (o in M language) in un’unica query nativa — tipicamente SQL — che viene inviata all’origine dati ed eseguita direttamente lì. Invece di scaricare l’intera tabella e trasformarla in memoria sulla macchina che ospita il mashup engine, Power BI delega il lavoro pesante (filtri, join, aggregazioni, selezione colonne) al database sorgente, che è ottimizzato per quel tipo di operazioni.

Il beneficio è duplice: meno dati trasferiti sulla rete e meno carico sul motore di Power BI. Un Table.SelectRows che filtra Year = 2026 diventa una WHERE clause: l’origine restituisce solo le righe utili, non milioni di record da scartare in seguito. Su origini relazionali (SQL Server, Azure SQL, PostgreSQL, sorgenti OData) il folding è pienamente supportato; su file (CSV, Excel, JSON) non esiste, perché non c’è un motore query a valle a cui delegare.

Verificare il folding con View Native Query

Il metodo diretto è nel riquadro Applied Steps: click destro su uno step → View Native Query. Se la voce è attiva, quello step (e tutti i precedenti) sono stati “piegati” in una singola istruzione nativa che puoi ispezionare. Se è disabilitata (grigia), il folding si è interrotto a quello step o prima: da quel punto in poi Power Query elabora i dati localmente.

  • Controlla sempre l’ultimo step foldable: è lì che si misura fin dove arriva la delega all’origine.
  • In alternativa, il Query Diagnostics mostra le query effettivamente inviate al database.

Cosa rompe il folding

Non tutte le trasformazioni sono traducibili in query nativa. Tipicamente spezzano la catena:

  • Colonne custom con logica M complessa o funzioni non mappabili in SQL (Table.AddColumn con espressioni arbitrarie).
  • Table.AddIndexColumn (indice/riga progressiva).
  • Merge tra query con origini diverse o tipi non allineati.
  • Molte funzioni di manipolazione testo/data specifiche di M che non hanno equivalente SQL.
  • Passaggi su origini non-foldable per natura (file, alcune API, input manuali).

Il punto architetturale cruciale: il folding si valuta step per step in sequenza. Nel momento in cui inserisci uno step non-foldable, tutti gli step successivi — anche quelli che sarebbero perfettamente traducibili — vengono eseguiti in locale. Un semplice SelectRows messo dopo una colonna custom non viene più delegato, e ti ritrovi a scaricare l’intera tabella per filtrarla sul client.

Perché mantenerlo il più a lungo possibile

La strategia corretta è ordinare gli step in modo che le operazioni foldable e riduttive (filtri righe, rimozione colonne, aggregazioni) stiano all’inizio, e le trasformazioni non-foldable il più tardi possibile, quando il volume di dati è già ridotto.

Il caso più importante è l’incremental refresh: Power BI implementa il refresh incrementale filtrando per intervallo di date tramite i parametri RangeStart/RangeEnd. Questi filtri devono foldare fino all’origine, altrimenti il servizio scaricherebbe comunque tutta la tabella per poi filtrarla localmente, annullando ogni vantaggio. Se il folding è rotto a monte del filtro di data, l’incremental refresh o fallisce nella configurazione o degenera in un full refresh mascherato. Query folding intatto sulla colonna di partizionamento è un prerequisito, non un’ottimizzazione opzionale.

Trappole tipiche d’esame

  • Scenario: una query SQL Server è lenta e trasferisce troppi dati; un Add Custom Column è il secondo step, prima dei filtri. → Risposta giusta: spostare la colonna custom dopo i filtri e le rimozioni colonne, così i filtri restano foldable; verificare con View Native Query.
  • Scenario: devi configurare incremental refresh ma il refresh scarica sempre tutto. → Risposta giusta: garantire che il filtro RangeStart/RangeEnd foldi fino all’origine; la sorgente deve supportare il folding (relazionale), non un file.
  • Scenario: vuoi sapere se uno step è delegato all’origine. → Risposta giusta: click destro sullo step → View Native Query; se è grigio, il folding si è interrotto.
  • Scenario: origine dati è un file CSV/Excel e ci si aspetta il folding. → Risposta giusta: i file non supportano il query folding; per grandi volumi serve un’origine con query engine (DB relazionale, Fabric warehouse/lakehouse SQL endpoint).
  • Scenario: Table.AddIndexColumn inserito presto degrada le performance a valle. → Risposta giusta: è uno step non-foldable; posizionarlo alla fine, dopo che le operazioni riduttive sono già state delegate.