Il semantic model in Fabric

Un semantic model (l’evoluzione del vecchio “dataset” di Power BI) è lo strato tabellare che espone tabelle, relazioni, gerarchie e misure DAX ai report. In Fabric ogni Lakehouse e ogni Warehouse ne genera automaticamente uno di default, ma per scenari produttivi conviene creare un semantic model custom che seleziona solo le tabelle rilevanti e definisce misure, relazioni e RLS in modo controllato.

La scelta chiave è la storage mode della tabella: Import (copia i dati nella cache in-memory VertiPaq, veloce ma con refresh schedulati), DirectQuery (interroga la sorgente a ogni query, sempre fresco ma lento) oppure Direct Lake, la modalità nativa e distintiva di Fabric.

Come funziona Direct Lake

Direct Lake legge direttamente i file Delta/Parquet di OneLake e li carica in memoria nel motore VertiPaq on demand, colonna per colonna, senza produrre una copia importata e senza un refresh classico. Il risultato è che combina:

  • le prestazioni dell’Import (query servite dalla cache in-memory columnare);
  • la freschezza del DirectQuery (i dati provengono direttamente dai file Delta più recenti in OneLake).

Il caricamento in memoria si chiama transcoding: le colonne effettivamente usate dalle query vengono “paginate” in VertiPaq e mantenute in cache; quelle non richieste non occupano memoria. Non esiste quindi un refresh che ricarica l’intero modello.

Reframing vs refresh

Quando le tabelle Delta sottostanti cambiano (nuova versione, INSERT, OPTIMIZE, MERGE), il semantic model deve puntare all’ultima versione dei file. Questa operazione si chiama reframing: aggiorna i metadati del modello alla versione corrente del Delta log e invalida le colonne in cache che vanno ricaricate al prossimo accesso. Il reframing è tipicamente automatico, ma può essere forzato con un refresh del semantic model (via UI, pipeline o API) — utile per allineare i dati subito dopo un job di ingestion invece di attendere il polling. Come data engineer devi monitorare reframing e refresh perché una pipeline che riscrive la tabella subito dopo un reframing può causare letture su versioni non più ottimali o picchi di ricaricamento colonne.

Fallback automatico a DirectQuery

Direct Lake non può sempre servire una query dalla memoria. In questi casi ricade automaticamente su DirectQuery verso l’SQL analytics endpoint, in modo trasparente ma più lento. Le cause principali:

  • Superamento dei guardrail di capacity: ogni SKU Fabric (F2, F64, ecc.) impone limiti su righe per tabella e numero di file Parquet / row group. Oltre soglia, la tabella cade in DirectQuery.
  • Feature non supportate in Direct Lake: alcune viste SQL, tipi di dato o costrutti non gestiti nativamente.

Il comportamento è governato dalla proprietà DirectLakeBehavior: Automatic (default, con fallback), DirectLakeOnly (nessun fallback: le query non servibili falliscono — utile per garantire performance prevedibili e scoprire i limiti in test) e DirectQueryOnly. Con Direct Lake on OneLake è inoltre possibile combinare in un unico modello tabelle Direct Lake con tabelle Import/DirectQuery (composite model).

L’impatto del V-Order

V-Order è un’ottimizzazione applicata in scrittura ai file Parquet (sorting, riordino dei row group, dictionary encoding e compressione) che li rende molto più efficienti da leggere per il motore VertiPaq, pur restando Parquet standard e open. È determinante per Direct Lake: file V-Ordered si caricano in memoria più velocemente e con minore footprint, riducendo la probabilità di sforare i guardrail e finire in fallback.

  • È attivo di default sulle scritture del motore Fabric, ma può essere disabilitato per privilegiare la velocità di ingestion write-heavy.
  • Job manutentivi come OPTIMIZE (compattazione dei file piccoli) e V-Order mantengono la tabella performante nel tempo.

Trappole tipiche d’esame

  • Scenario: i dati devono essere sempre aggiornati ma serve la velocità dell’import, senza refresh schedulato → risposta: usa un semantic model in Direct Lake, non Import con refresh né DirectQuery.
  • Scenario: dopo aver caricato dati in un Lakehouse le query rallentano drasticamente su tabelle enormi → risposta: la tabella ha superato i guardrail di capacity ed è in fallback DirectQuery; sali di SKU o riduci il volume/file.
  • Scenario: le query devono garantire performance costanti e non devono mai degradare silenziosamente → risposta: imposta DirectLakeBehavior = DirectLakeOnly per far fallire (anziché rallentare) ciò che non è servibile in-memory.
  • Scenario: dopo un OPTIMIZE il report non riflette subito i nuovi file → risposta: forza un refresh/reframing del semantic model per puntare all’ultima versione Delta.
  • Scenario: le letture Direct Lake sono lente perché i Parquet non sono ottimizzati → risposta: assicurati che sia attivo il V-Order ed esegui OPTIMIZE, non passare a Import.