SlideShare ist ein Scribd-Unternehmen logo
1 von 44
Downloaden Sie, um offline zu lesen
#sqlsat589February 25th, 2017
Optimizing DAX
Marco Pozzan
#sqlsat589February 25th, 2017
Sponsor
#sqlsat589February 25th, 2017
Organizers
#sqlsat589February 25th, 2017
Chi sono
 Community Lead 1nn0va (www.innovazionefvg.net)
 Consulente Business Intelligence per (www.beantech.it)
 Docente ITS all’Università di Pordenone
 Partecipo agli eventi community
 info@marcopozzan.it
 @marcopozzan.it
 www.marcopozzan.it
 http://www.scoop.it/u/marco-pozzan
 http://paper.li/marcopozzan/1422524394
#sqlsat589February 25th, 2017
Agenda
 La differenza tra FE ed SE
 Tipi di query plan
 Tool per ottimizzare DAX
 Recap su Vertipaq
 Ottimizzazioni di DAX
 Conclusioni
#sqlsat589February 25th, 2017
 In Vertipaq ci sono due motori completamente diversi come
caratteristiche, sono come due fratellini che assieme cercano di
risolvere la query DAX
 Storage engine
 Formula engine
 Lo storage engine va sullo storage scandisce il contenuto delle tabelle e
restituisce sempre tabelle come risultato
 Le tabelle che restituisce lo storage engine sono utilizzate dal formula
engine per fare ulteriori calcoli
(SE) e (FE)
#sqlsat589February 25th, 2017
 Storage engine (SE):
 è incredibilmente veloce
 è multi-thread quindi lavora su più core ed è in grado di parallelizzare moltissimo
 non sa fare molte operazioni: select, matematica di bassissimo livello, applica
un filtro where e segue le relazioni per join
 Formula engine (FE):
 Tutte le altre operazioni vengono risolte da formula engine
 Single-thread
 Espressività
 Considerazioni: bisogna codificare le query DAX in modo che si ottimizzi
l’uso di SE e si riduca il l’uso di FE perchè così si ha più velocità
(SE) e (FE)
#sqlsat589February 25th, 2017
 Ogni task eseguito da SE va in cache e quindi produrranno un risultato
veloce la seconda volta che viene eseguito
 Ogni compito eseguito da FE non va in cache e viene ripetuto di nuovo
 Per creare delle buone ottimizzazioni analizziamo come vertipaq lavora
con e senza cache. Per svuotare la chace si utilizza il seguente script
 Considerazioni: fare in modo che le parti delle nostre query utilizzino il
meno possibile FE in quanto sono parti che vengono ogni volta
ricalcolate
Cosa viene messo nella cache
#sqlsat589February 25th, 2017
 Il «DAX Query Plan» indica ciò che Vertipaq farà. Ci sono due tipi di
query plan:
 Logical query plan: praticamente inutile perchè descrive la definizione
dell’algoritmo della query DAX e a patto che la query non sia molto complessa
non contiene informazioni importanti
 Fisical query plan: molto utile e ci dice quello che effettivamente ha fatto la
query.
 Il query plan in tabular non è come sql che mostra frecce e colori ma è
una stringa di testo
Query plan
#sqlsat589February 25th, 2017
Query plan Optimization Flow
Build DAX Expression Tree
Build DAX Logical Plan
Simplify DAX Logical Plan
Build DAX Physical Plan
Execute DAX Physical Plan
Fire Logical Plan Event
Fire Physical Plan Event
#sqlsat589February 25th, 2017
 Profiler SQL Server
 DAX Studio (https://daxstudio.codeplex.com/)
Tool per le ottimizzazioni
#sqlsat589February 25th, 2017
 Query End: E’ un evento che viene generato quando si cocnlude la query e riporta il
tempo di esecuzione totale delle query e il tempo di lavoro della CPU
 Dax Query Plan: è un evento che viene generato quando viene creato il query plan e
genera la forma testuale del query plan
 Vertipaq SE Query Cache Match: questo evento accade quando una query Vertipaq
viene eseguita usando la cache
 Vertipaq SE Query End: è l’evento che si genera quando viene eseguita una query dallo
Storage Engine di Vertipaq per ritornare il risultato
Eventi che catturano i tool
#sqlsat589February 25th, 2017
 Vediamo come viene risolta questa query
 SQL Profiler
 DAX Studio
Come lavorano?
#sqlsat589February 25th, 2017
DAX query plan (logical plan)
AddColumns : RelLogOp DependOnCols()() 0-0 Parametri Operatori
RequiredCols(0)(''[Result])
Sum_Vertipaq: ScaLogOp DependOnCols()() Tipo Operatore
Currency DominantValue=BLANK
Scan_Vertipaq: RelLogOp
DependOnCols()() 0-135
RequiredCols(126)('Internet
Sales Big'[Sales Amount])
'Internet Sales'[Sales Amount]: ScaLogOp DependOnCols(126)('Internet
Sales Big'[Sales Amount]) Currency
DominantValue=NONE
EVALUATE
row ("Result",
SUM(
'Internet Sales Big'[Sales
Amount]
))Operatore
Operazioni
eseguite
Da Vertipaq
SQL Profiler DAX Studio
#sqlsat589February 25th, 2017
 Column List (Elenco numero di colonna) (elenco nomi di colonna). RequiredCols (0, 1) ( 'Data'
[CalendarYear], ‘Internet Sales Big' [SalesAmount]) o DependOnCols () ()
 La ScaLogOp indica una dipendenza sul ramo sinistro DependOnCols(126) e ritorna uno scalare
 sotto RelLogOp ci sono le Vertipaq query ritorna una tabella
 «Crea una tabella con una colonna result che sarà riempita dalla SUM (SUM_Vertipaq) sulla colonna
[Sales Amount] leggendo tutta la tabella (Scan_Vertipaq) Internet Sales Big»
DAX query plan (logical plan)
AddColumns : RelLogOp DependOnCols()() 0-0
RequiredCols(0)(''[Result])
Sum_Vertipaq: ScaLogOp DependOnCols()()
Currency DominantValue=BLANK
Scan_Vertipaq: RelLogOp
DependOnCols()() 0-135
RequiredCols(126)('Internet
Sales Big'[Sales Amount])
'Internet Sales'[Sales Amount]: ScaLogOp
DependOnCols(126)('Internet Sales Big'[Sales Amount]) Currency DominantValue=NONE
AddColumns
RelLog
Op
SubTree
ScaLog
OpVertipaq Query
1
2
#sqlsat589February 25th, 2017
 SinglestonTable è una tabella con una riga che rappresenta il comando ROW = [Result]
 SpoolLookup i dati per result li cerca nella datacache che si chiama “ProjectFusion<Sum>“
 ProjectionSpool nuova versione di AggrgationSpool contiene il risultato della VertipaqResult
importante l’etichetta #Records che sono il numero di righe in cache che sono usate
 VertipaqResult risultato di una query xmlSQL. Ma non si sa quale query 
 #ValueCols n° di colonne numeriche e #FieldCols n° di colonne di altro tipo
DAX query plan (physical plan)
AddColumns: IterPhyOp LogOp=AddColumns IterCols(0)(''[Result])
SingletonTable: IterPhyOp LogOp=AddColumns IterCols(0)(''[Result])
SpoolLookup: LookupPhyOp LogOp=Sum_Vertipaq Currency
#Records=1 #KeyCols=258 #ValueCols=1
DominantValue=BLANK
ProjectionSpool<ProjectFusion<Sum>>: SpoolPhyOp #Records=1
VertipaqResult: IterPhyOp #FieldCols=0 #ValueCols=1
#sqlsat589February 25th, 2017
Vertipaq SE query
 l’ FE genera una serie di operazioni che vengono inviate all’ SE
 Quello che è eseguito da SE nel profiler è il «vertipaq SE query» (xmSQL).
 Ci sono sempre 2 Vertipaq SE query.
 vertipaq scan è quello che chiede FE all’ SE
 vertipaq scan internal è quello che viene effettivamente eseguito da SE
SQL Profiler
DAX Studio
#sqlsat589February 25th, 2017
Query End
 Query End ha una durata (Duration) e (CPUTime) in millisecondi
 CPUTime = SE CPU =tempo eseguito per query (x tanti utenti devo ridurlo)
 Duration = Total = tempo di attesa del risultato (diviso per n° core) (se ho
pochi utenti devo ridurlo e non me ne frega che la CPU sia 100%)
 Se ho due thred in parallelo uno per core la Duration <= CPUTime
 123 ms di SE (sommatoria dei Vertipaq Scan), 125-123 = 2 FE
 Quando i due sono sotto i 10-15 millesecondi non ha senso ottimizzare
SQL Profiler DAX Studio
#sqlsat589February 25th, 2017
Compressione in Vertipaq
 Vertipaq (simile compressione di pagina in SQL Server)
 Identifica parti uguali nell’aria di memoria
 Crea una struttura per rappresentare le parti uguali e ottiene la struttura
compressa della colonna
 Più efficiente di SQL perché si ragiona solo su una colonna con pochi
valori distinti rispetto alla pagina di SQL in cui ho righe con più colonne e
con meno valori distinti .
Vediamo come Vertipaq esegue la compressione
#sqlsat589February 25th, 2017
Run Length Encoding (RLE) - 1 livello
Potrei anche decidere di
togliere la colonna inizio
e tenere solo la fine
Children
1
1
1
1
1
...
2
2
2
2
2
2
2
2
....
Children Inizio Lunghezza
1 1 200
2 201 400
FirstName
Larry
Larry
Larry
...
Geoffrey
Geoffrey
Geoffrey
...
Alexa
Alexa
Alexa
...
Colleen
Colleen
...
FirstName Lunghezza
Larry 400
Geoffrey 400
Alexa 100
Colleen 100
BirthDate
13/04/1977
13/05/1977
13/06/1977
....
15/04/1980
16/04/1947
13/04/1976
...
13/04/1976
13/04/1976
13/04/1976
...
13/04/1990
13/04/1934
...
BirthDate lunghezza
13/04/1977 1
13/05/1977 1
13/06/1977 1
....
15/04/1980 1
16/04/1947 1
13/04/1976 1
...
13/04/1976 1
13/04/1976 1
13/04/1976 1
...
13/04/1990 1
13/04/1934 1
...
Le date cambiano così di frequente che se
provassi a comprimerla avrei su lunghezza
tutti 1 e otterrei una tabella più grande
dell’originale. Vertipaq lascia l’originale.
#sqlsat589February 25th, 2017
Run Length Encoding (RLE) - 1 livello
 Vertipaq non usa mai più memoria rispetto alla colonna sorgente…se non
riesce a comprimerla la lascia come è
 Vertipaq durante il processing di un tabella
 Divide la tabella in colonne
 Comprime ogni colonna con RLE
 Obbiettivo 1 L’ordinamento delle colonne è il punto più importante per
RLE (se ne occupa vertipaq ) buon ordinamento = buona
compressione
 Obbiettivo 2 : Se la dimensione della colonna in memoria è bassa lo
scan sarà più veloce
#sqlsat589February 25th, 2017
Dictionary encoding - 2 livello
Conoscendo i possibili valori della
stringa utilizzo il numero minimo di
bit per rappresentarla. In questo
caso 4 possibili valori bastano 2 bit.
Creo il
dizionario
Quarter
Q1
Q4
Q1
...
Q2
Q3
Q1
...
Q3
Q3
Q2
...
Q1
Q1
....
DISTINCT
Indice Quarter
1 Q1
2 Q2
3 Q3
4 Q4
Quarter
1
1
1
...
2
2
2
...
3
3
3
...
4
4
....
SOSTITUISCI
RLE
Quarter Count Lunghezza
1 1 400
2 400 400
3 800 100
4 900 100
xVelocity storage
Con il dictionary encoding Vertipaq è datatyping
independent. Non ha nessuna importanza il tipo dei campi
che si utilizzano nelle viste per popolare il modello
Indice Quarter
1 Q1
2 Q2
3 Q3
4 Q4
Versionecompressa
Dizionario
#sqlsat589February 25th, 2017
Conclusioni su RLE e Dictionary encoding
 Una stringa nella tabella dei fatti (osceno) non ha più nessun
prezzo grazie al dictionary encoding
 Obbiettivo 1: Importa solo il numero di valori distinti delle colonne
 Tanti valori distinti occupano più spazio (+ RAM) ed più lungo a
fare analisi
 Pochi valori distinti occupano poco spazio (- RAM) e tutte
operazioni ridotte
#sqlsat589February 25th, 2017
 Long Scan Time: Spesso per aggregazioni semplici le query DAX fanno
lo scan su una o piu colonne. Il costo di questa scan dipende dalla
dimensione delle colonne che dipende dal numero di valori distinti e
loro distribuzione
 Large Cardinality: Un largo numero di valori univoci in una colonna può
dare noia alla DISTINCTCOUNT
 Alta frequenza di CallbackDataID: Un largo numero di chiamate dallo
storage engine al formula engine possono influire pesantemente sulle
performance
 Large Materializzation: Se uno Storage Engine produce una grande
datacache la sua generazione richiede tempo (allocamento di RAM)
Cause dei bottlenecks nello storage engine
#sqlsat589February 25th, 2017
Demo 0
#sqlsat589February 25th, 2017
Demo 0
 La sum è sensibile alla dimensione perchè deve fare lo scan della
tabella quindi deve fare lo scan di tutte le colonne
 La distinctcount dipende dalla cardinalità
 N.B. Ridurre il numero di valori distinti velocizza le query 
Colonna Memoria (MB) Valori distinti SUM DISTINCTCOUNT
Sales Amount 1,855,587,152 40,000 809 2023
TimeKey 1,237,296,936 86,400 526 2556
#sqlsat589February 25th, 2017
Demo 1
 Eseguiamo la seguente formula DAX
 Genera un query plan che con due scansioni due coppie di Vertipaq Scan
SQL Profiler DAX Studio
#sqlsat589February 25th, 2017
Demo 1 – Perchè due query SE?
 1° Vertiaq Scan estrae CalendarYear da Date e la somma di Sales
Amount da Internet Sales. Usa solo SE perchè sono operazioni che sa fare
 Se la prima query risolve tutto perchè c’è una 2° Internal Vertiaq Scan?
 La seconda restituisce gli anni e la prima le vendite e anni e poi metto
assieme con FE
#sqlsat589February 25th, 2017
Demo 1 – Considerazioni sull’ottimizzazione
 Recupera gli anni dalla tabella dei fatti
 Che senso ha fare la scansione della tabella dei fatti per gli anni?
 Secondo voi quale è la maniera più veloce per recuperare tutte le date?
 Analizzando la tabella dei fatti (77.309.440 rows)
 Analizzando la tabella della dimensione Date (3652 rows)
#sqlsat589February 25th, 2017
Demo 2 – SUMMARIZE vs ADDCOLUMNS
 Con la nuova query si azzera il tempo per recuperare l’anno
SQL Profiler DAX Studio
#sqlsat589February 25th, 2017
Demo 2 – SUMMARIZE vs ADDCOLUMNS
 Con la SUMMURIZE al posto di VALUE peggioro le performance ma scrivo
meno DAX
 E se uso SUMMARIZECOLUMNS (Dax 2015) ?
#sqlsat589February 25th, 2017
 Una summarize dove aggreghiamo sia per anno che per colore.
 2° Vertipaq Scan per recuperare anno e colore fa uno scan su tabella fatti
Demo 3 – Problema SUMMARIZE con più colonne
SQL Profiler DAX Studio
#sqlsat589February 25th, 2017
Demo 3 – Soluzione
 Utilizzamo la ADDCOLUMNS con CROSSJOIN per ottimizzare la formula
 Le Vertipaq Scan aumentano da 2 a 3 perchè viene eseguita una
Internal Vertipaq Scan secca sulla tabella prodotti e calendario
SQL Profiler DAX Studio
#sqlsat589February 25th, 2017
 Con ROLLUP possiamo ottenere il venduto per anno e colore , il totale
per anno e colore e il grand total per anno.
Ci sono due modi di operare:
 Generazione di più query SE per recuperare i sottototali e per il grand total
(l’unica possibile)
 Recuperare il dettaglio e poi aggregare all’interno di FE per (questo solo se sono
sicuro che sono additive)
Demo 4 – ROLLUP
#sqlsat589February 25th, 2017
Demo 4 – ROLLUP
 Come si vede il numero di query SE è aumentato di molto
 la ROLLUP aumenta la complessità di (2N + 1) volte (N n° parametri)
(subtotali su 2 livelli =>2n+1=5 scansioni, 3 livelli =>3n+1=7 scansioni...)
SQL Profiler DAX Studio
#sqlsat589February 25th, 2017
 Esaminiamo la seguente query DAX
 I callbackDataID sono richieste di aiuto di SE a FE in
quanto non sa fare IF  e chiede a FE di eseguirlo.
Funziona ma ci sono due problemi:
 uno è multi-thread e l’altro no
 si parla di elaborazione di FE e quindi non si usa la cache
Demo 5 – CallbackDataID
#sqlsat589February 25th, 2017
Demo 5 – CallbackDataID
 Anche se uso DIVIDE ho sempre la callbackID anche se è un pò più
veloce
#sqlsat589February 25th, 2017
Demo 5 – CallbackDataID
 Riscriviamo la formula per levare la CallBackDataID
#sqlsat589February 25th, 2017
 La SUMX non si comporta come una iterazione perchè viene eseguita
direttamente da Vertipaq in quanto la sa gestire
Demo 5 – CallbackDataID non avviene con le interazioni
singole
#sqlsat589February 25th, 2017
 doppia iterazione genera un CallbackDataID
Demo 5 – CallbackDataID avviene con le interazioni annidate
#sqlsat589February 25th, 2017
 Vogliamo ottenere i 50 prodotti che hanno vendite maggiori
Demo 6 – Riduciamo la materializzazione
Dobbiamo ridurre
la dimensione della
datacache che in
questo caso è di 79
KB
#sqlsat589February 25th, 2017
 Dobbiamo ridurre la dimensione della Datacache
Demo 6 – Riduciamo la materializzazione
#sqlsat589February 25th, 2017
 Capire come funzionano SE e FE
 Ridurre FE, aumentare SE
 Leggere i query plan rende possibile l’ottimizzazione
 DAX non è facile da ottimizzare.... Ma è meglio che con MDX
 Libro di riferimento da cui partire
 https://www.sqlbi.com/books/the-definitive-guide-to-dax/
 Link di riferimento per approfondire
 http://www.sqlbi.com/wp-content/uploads/DAX-Query-Plans.pdf
 http://www.sqlbi.com/wp-content/uploads/Understanding-Distinct-Count-in-
DAX-Query-Plans.pdf
Conclusioni
#sqlsat589February 25th, 2017
THANKS! Q&A
#sqlsat589

Weitere ähnliche Inhalte

Ähnlich wie Optimizing dax

Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1
Alberto.F
 
Presentazione Nuvola Vertica Full New
Presentazione Nuvola Vertica Full NewPresentazione Nuvola Vertica Full New
Presentazione Nuvola Vertica Full New
Alberto.F
 
Confio Ignite - webinar by Matteo Durighetto
Confio Ignite - webinar by Matteo DurighettoConfio Ignite - webinar by Matteo Durighetto
Confio Ignite - webinar by Matteo Durighetto
Miriade Spa
 

Ähnlich wie Optimizing dax (20)

Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1
 
Presentazione Nuvola Vertica Full New
Presentazione Nuvola Vertica Full NewPresentazione Nuvola Vertica Full New
Presentazione Nuvola Vertica Full New
 
Marco Arena - Perché nel 2015 parliamo ancora di C++? | Codemotion Milan 2015
Marco Arena - Perché nel 2015 parliamo ancora di C++? | Codemotion Milan 2015Marco Arena - Perché nel 2015 parliamo ancora di C++? | Codemotion Milan 2015
Marco Arena - Perché nel 2015 parliamo ancora di C++? | Codemotion Milan 2015
 
[Ita] Sql Saturday 462 Parma - Sql Server 2016 JSON support
[Ita] Sql Saturday 462 Parma - Sql Server 2016 JSON support[Ita] Sql Saturday 462 Parma - Sql Server 2016 JSON support
[Ita] Sql Saturday 462 Parma - Sql Server 2016 JSON support
 
Digital 1nn0vation saturday pn 2019 - ML.NET
Digital 1nn0vation saturday pn 2019 - ML.NETDigital 1nn0vation saturday pn 2019 - ML.NET
Digital 1nn0vation saturday pn 2019 - ML.NET
 
[ITA] SQL Saturday 257 - Put databases under source control
[ITA] SQL Saturday 257 - Put databases under source control[ITA] SQL Saturday 257 - Put databases under source control
[ITA] SQL Saturday 257 - Put databases under source control
 
AWR analysis (o di come utilizzare l’AWR per condurre un’analisi di un databa...
AWR analysis (o di come utilizzare l’AWR per condurre un’analisi di un databa...AWR analysis (o di come utilizzare l’AWR per condurre un’analisi di un databa...
AWR analysis (o di come utilizzare l’AWR per condurre un’analisi di un databa...
 
Una PA agile, funzionale e serverless: si può fare! by Federico Feroldi and D...
Una PA agile, funzionale e serverless: si può fare! by Federico Feroldi and D...Una PA agile, funzionale e serverless: si può fare! by Federico Feroldi and D...
Una PA agile, funzionale e serverless: si può fare! by Federico Feroldi and D...
 
Una Pubblica Amministrazione Agile, Funzionale e Serverless: si può fare! - C...
Una Pubblica Amministrazione Agile, Funzionale e Serverless: si può fare! - C...Una Pubblica Amministrazione Agile, Funzionale e Serverless: si può fare! - C...
Una Pubblica Amministrazione Agile, Funzionale e Serverless: si può fare! - C...
 
Una PA agile, funzionale e serverless: si può fare! - Danilo Spinelli - Codem...
Una PA agile, funzionale e serverless: si può fare! - Danilo Spinelli - Codem...Una PA agile, funzionale e serverless: si può fare! - Danilo Spinelli - Codem...
Una PA agile, funzionale e serverless: si può fare! - Danilo Spinelli - Codem...
 
Giancarlo Ronci IT
Giancarlo Ronci ITGiancarlo Ronci IT
Giancarlo Ronci IT
 
MySQL Day Milano 2019 - Il backup non ammette ignoranza
MySQL Day Milano 2019 - Il backup non ammette ignoranzaMySQL Day Milano 2019 - Il backup non ammette ignoranza
MySQL Day Milano 2019 - Il backup non ammette ignoranza
 
Back to the roots - SQL Server Indexing
Back to the roots - SQL Server IndexingBack to the roots - SQL Server Indexing
Back to the roots - SQL Server Indexing
 
Confio Ignite - webinar by Matteo Durighetto
Confio Ignite - webinar by Matteo DurighettoConfio Ignite - webinar by Matteo Durighetto
Confio Ignite - webinar by Matteo Durighetto
 
TypeScript, ovvero JavaScript che "non si rompe"
TypeScript, ovvero JavaScript che "non si rompe"TypeScript, ovvero JavaScript che "non si rompe"
TypeScript, ovvero JavaScript che "non si rompe"
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
 
Oai Data Adapter
Oai Data AdapterOai Data Adapter
Oai Data Adapter
 
Basi Di Dati 05
Basi Di Dati 05Basi Di Dati 05
Basi Di Dati 05
 
14 faq400
14 faq40014 faq400
14 faq400
 
Visual Studio Performance Tools
Visual Studio Performance ToolsVisual Studio Performance Tools
Visual Studio Performance Tools
 

Mehr von Marco Pozzan

Power BI and business application platform
Power BI and business application platformPower BI and business application platform
Power BI and business application platform
Marco Pozzan
 

Mehr von Marco Pozzan (20)

Metadata Driven Pipeline with Microsoft Fabric
Metadata Driven Pipeline  with Microsoft FabricMetadata Driven Pipeline  with Microsoft Fabric
Metadata Driven Pipeline with Microsoft Fabric
 
Data Warehouse with Fabric on data lakehouse
Data Warehouse with Fabric on data lakehouseData Warehouse with Fabric on data lakehouse
Data Warehouse with Fabric on data lakehouse
 
Data modelling for Power BI
Data modelling for Power BIData modelling for Power BI
Data modelling for Power BI
 
SlideModellingDataSat.pdf
SlideModellingDataSat.pdfSlideModellingDataSat.pdf
SlideModellingDataSat.pdf
 
Datamart.pdf
Datamart.pdfDatamart.pdf
Datamart.pdf
 
Datamart.pptx
Datamart.pptxDatamart.pptx
Datamart.pptx
 
Quanto mi costa SQL Pool Serverless Synapse
Quanto mi costa SQL Pool Serverless SynapseQuanto mi costa SQL Pool Serverless Synapse
Quanto mi costa SQL Pool Serverless Synapse
 
Power BI: Introduzione ai dataflow e alla preparazione dei dati self-service
Power BI: Introduzione ai dataflow e alla preparazione dei dati self-servicePower BI: Introduzione ai dataflow e alla preparazione dei dati self-service
Power BI: Introduzione ai dataflow e alla preparazione dei dati self-service
 
Data flow
Data flowData flow
Data flow
 
Microsoft Power BI fast with aggregation and composite model
Microsoft Power BI fast with aggregation and composite modelMicrosoft Power BI fast with aggregation and composite model
Microsoft Power BI fast with aggregation and composite model
 
REAL TIME ANALYTICS INFRASTRUCTURE WITH AZURE
REAL TIME ANALYTICS INFRASTRUCTURE WITH AZUREREAL TIME ANALYTICS INFRASTRUCTURE WITH AZURE
REAL TIME ANALYTICS INFRASTRUCTURE WITH AZURE
 
Big data analytics quanto vale e come sfruttarlo con stream analytics e power bi
Big data analytics quanto vale e come sfruttarlo con stream analytics e power biBig data analytics quanto vale e come sfruttarlo con stream analytics e power bi
Big data analytics quanto vale e come sfruttarlo con stream analytics e power bi
 
What is in reality a DAX filter context
What is in reality a DAX filter contextWhat is in reality a DAX filter context
What is in reality a DAX filter context
 
Azure saturday pn 2018
Azure saturday pn 2018Azure saturday pn 2018
Azure saturday pn 2018
 
Power B: Cleaning data
Power B: Cleaning dataPower B: Cleaning data
Power B: Cleaning data
 
Power bi Clean and Modelling (SQL Saturday #675)
Power bi Clean and Modelling  (SQL Saturday #675)Power bi Clean and Modelling  (SQL Saturday #675)
Power bi Clean and Modelling (SQL Saturday #675)
 
Power BI and business application platform
Power BI and business application platformPower BI and business application platform
Power BI and business application platform
 
Optimizing dax
Optimizing daxOptimizing dax
Optimizing dax
 
Power bi + Flow
Power bi + FlowPower bi + Flow
Power bi + Flow
 
Power BI
Power BIPower BI
Power BI
 

Optimizing dax

  • 4. #sqlsat589February 25th, 2017 Chi sono  Community Lead 1nn0va (www.innovazionefvg.net)  Consulente Business Intelligence per (www.beantech.it)  Docente ITS all’Università di Pordenone  Partecipo agli eventi community  info@marcopozzan.it  @marcopozzan.it  www.marcopozzan.it  http://www.scoop.it/u/marco-pozzan  http://paper.li/marcopozzan/1422524394
  • 5. #sqlsat589February 25th, 2017 Agenda  La differenza tra FE ed SE  Tipi di query plan  Tool per ottimizzare DAX  Recap su Vertipaq  Ottimizzazioni di DAX  Conclusioni
  • 6. #sqlsat589February 25th, 2017  In Vertipaq ci sono due motori completamente diversi come caratteristiche, sono come due fratellini che assieme cercano di risolvere la query DAX  Storage engine  Formula engine  Lo storage engine va sullo storage scandisce il contenuto delle tabelle e restituisce sempre tabelle come risultato  Le tabelle che restituisce lo storage engine sono utilizzate dal formula engine per fare ulteriori calcoli (SE) e (FE)
  • 7. #sqlsat589February 25th, 2017  Storage engine (SE):  è incredibilmente veloce  è multi-thread quindi lavora su più core ed è in grado di parallelizzare moltissimo  non sa fare molte operazioni: select, matematica di bassissimo livello, applica un filtro where e segue le relazioni per join  Formula engine (FE):  Tutte le altre operazioni vengono risolte da formula engine  Single-thread  Espressività  Considerazioni: bisogna codificare le query DAX in modo che si ottimizzi l’uso di SE e si riduca il l’uso di FE perchè così si ha più velocità (SE) e (FE)
  • 8. #sqlsat589February 25th, 2017  Ogni task eseguito da SE va in cache e quindi produrranno un risultato veloce la seconda volta che viene eseguito  Ogni compito eseguito da FE non va in cache e viene ripetuto di nuovo  Per creare delle buone ottimizzazioni analizziamo come vertipaq lavora con e senza cache. Per svuotare la chace si utilizza il seguente script  Considerazioni: fare in modo che le parti delle nostre query utilizzino il meno possibile FE in quanto sono parti che vengono ogni volta ricalcolate Cosa viene messo nella cache
  • 9. #sqlsat589February 25th, 2017  Il «DAX Query Plan» indica ciò che Vertipaq farà. Ci sono due tipi di query plan:  Logical query plan: praticamente inutile perchè descrive la definizione dell’algoritmo della query DAX e a patto che la query non sia molto complessa non contiene informazioni importanti  Fisical query plan: molto utile e ci dice quello che effettivamente ha fatto la query.  Il query plan in tabular non è come sql che mostra frecce e colori ma è una stringa di testo Query plan
  • 10. #sqlsat589February 25th, 2017 Query plan Optimization Flow Build DAX Expression Tree Build DAX Logical Plan Simplify DAX Logical Plan Build DAX Physical Plan Execute DAX Physical Plan Fire Logical Plan Event Fire Physical Plan Event
  • 11. #sqlsat589February 25th, 2017  Profiler SQL Server  DAX Studio (https://daxstudio.codeplex.com/) Tool per le ottimizzazioni
  • 12. #sqlsat589February 25th, 2017  Query End: E’ un evento che viene generato quando si cocnlude la query e riporta il tempo di esecuzione totale delle query e il tempo di lavoro della CPU  Dax Query Plan: è un evento che viene generato quando viene creato il query plan e genera la forma testuale del query plan  Vertipaq SE Query Cache Match: questo evento accade quando una query Vertipaq viene eseguita usando la cache  Vertipaq SE Query End: è l’evento che si genera quando viene eseguita una query dallo Storage Engine di Vertipaq per ritornare il risultato Eventi che catturano i tool
  • 13. #sqlsat589February 25th, 2017  Vediamo come viene risolta questa query  SQL Profiler  DAX Studio Come lavorano?
  • 14. #sqlsat589February 25th, 2017 DAX query plan (logical plan) AddColumns : RelLogOp DependOnCols()() 0-0 Parametri Operatori RequiredCols(0)(''[Result]) Sum_Vertipaq: ScaLogOp DependOnCols()() Tipo Operatore Currency DominantValue=BLANK Scan_Vertipaq: RelLogOp DependOnCols()() 0-135 RequiredCols(126)('Internet Sales Big'[Sales Amount]) 'Internet Sales'[Sales Amount]: ScaLogOp DependOnCols(126)('Internet Sales Big'[Sales Amount]) Currency DominantValue=NONE EVALUATE row ("Result", SUM( 'Internet Sales Big'[Sales Amount] ))Operatore Operazioni eseguite Da Vertipaq SQL Profiler DAX Studio
  • 15. #sqlsat589February 25th, 2017  Column List (Elenco numero di colonna) (elenco nomi di colonna). RequiredCols (0, 1) ( 'Data' [CalendarYear], ‘Internet Sales Big' [SalesAmount]) o DependOnCols () ()  La ScaLogOp indica una dipendenza sul ramo sinistro DependOnCols(126) e ritorna uno scalare  sotto RelLogOp ci sono le Vertipaq query ritorna una tabella  «Crea una tabella con una colonna result che sarà riempita dalla SUM (SUM_Vertipaq) sulla colonna [Sales Amount] leggendo tutta la tabella (Scan_Vertipaq) Internet Sales Big» DAX query plan (logical plan) AddColumns : RelLogOp DependOnCols()() 0-0 RequiredCols(0)(''[Result]) Sum_Vertipaq: ScaLogOp DependOnCols()() Currency DominantValue=BLANK Scan_Vertipaq: RelLogOp DependOnCols()() 0-135 RequiredCols(126)('Internet Sales Big'[Sales Amount]) 'Internet Sales'[Sales Amount]: ScaLogOp DependOnCols(126)('Internet Sales Big'[Sales Amount]) Currency DominantValue=NONE AddColumns RelLog Op SubTree ScaLog OpVertipaq Query 1 2
  • 16. #sqlsat589February 25th, 2017  SinglestonTable è una tabella con una riga che rappresenta il comando ROW = [Result]  SpoolLookup i dati per result li cerca nella datacache che si chiama “ProjectFusion<Sum>“  ProjectionSpool nuova versione di AggrgationSpool contiene il risultato della VertipaqResult importante l’etichetta #Records che sono il numero di righe in cache che sono usate  VertipaqResult risultato di una query xmlSQL. Ma non si sa quale query   #ValueCols n° di colonne numeriche e #FieldCols n° di colonne di altro tipo DAX query plan (physical plan) AddColumns: IterPhyOp LogOp=AddColumns IterCols(0)(''[Result]) SingletonTable: IterPhyOp LogOp=AddColumns IterCols(0)(''[Result]) SpoolLookup: LookupPhyOp LogOp=Sum_Vertipaq Currency #Records=1 #KeyCols=258 #ValueCols=1 DominantValue=BLANK ProjectionSpool<ProjectFusion<Sum>>: SpoolPhyOp #Records=1 VertipaqResult: IterPhyOp #FieldCols=0 #ValueCols=1
  • 17. #sqlsat589February 25th, 2017 Vertipaq SE query  l’ FE genera una serie di operazioni che vengono inviate all’ SE  Quello che è eseguito da SE nel profiler è il «vertipaq SE query» (xmSQL).  Ci sono sempre 2 Vertipaq SE query.  vertipaq scan è quello che chiede FE all’ SE  vertipaq scan internal è quello che viene effettivamente eseguito da SE SQL Profiler DAX Studio
  • 18. #sqlsat589February 25th, 2017 Query End  Query End ha una durata (Duration) e (CPUTime) in millisecondi  CPUTime = SE CPU =tempo eseguito per query (x tanti utenti devo ridurlo)  Duration = Total = tempo di attesa del risultato (diviso per n° core) (se ho pochi utenti devo ridurlo e non me ne frega che la CPU sia 100%)  Se ho due thred in parallelo uno per core la Duration <= CPUTime  123 ms di SE (sommatoria dei Vertipaq Scan), 125-123 = 2 FE  Quando i due sono sotto i 10-15 millesecondi non ha senso ottimizzare SQL Profiler DAX Studio
  • 19. #sqlsat589February 25th, 2017 Compressione in Vertipaq  Vertipaq (simile compressione di pagina in SQL Server)  Identifica parti uguali nell’aria di memoria  Crea una struttura per rappresentare le parti uguali e ottiene la struttura compressa della colonna  Più efficiente di SQL perché si ragiona solo su una colonna con pochi valori distinti rispetto alla pagina di SQL in cui ho righe con più colonne e con meno valori distinti . Vediamo come Vertipaq esegue la compressione
  • 20. #sqlsat589February 25th, 2017 Run Length Encoding (RLE) - 1 livello Potrei anche decidere di togliere la colonna inizio e tenere solo la fine Children 1 1 1 1 1 ... 2 2 2 2 2 2 2 2 .... Children Inizio Lunghezza 1 1 200 2 201 400 FirstName Larry Larry Larry ... Geoffrey Geoffrey Geoffrey ... Alexa Alexa Alexa ... Colleen Colleen ... FirstName Lunghezza Larry 400 Geoffrey 400 Alexa 100 Colleen 100 BirthDate 13/04/1977 13/05/1977 13/06/1977 .... 15/04/1980 16/04/1947 13/04/1976 ... 13/04/1976 13/04/1976 13/04/1976 ... 13/04/1990 13/04/1934 ... BirthDate lunghezza 13/04/1977 1 13/05/1977 1 13/06/1977 1 .... 15/04/1980 1 16/04/1947 1 13/04/1976 1 ... 13/04/1976 1 13/04/1976 1 13/04/1976 1 ... 13/04/1990 1 13/04/1934 1 ... Le date cambiano così di frequente che se provassi a comprimerla avrei su lunghezza tutti 1 e otterrei una tabella più grande dell’originale. Vertipaq lascia l’originale.
  • 21. #sqlsat589February 25th, 2017 Run Length Encoding (RLE) - 1 livello  Vertipaq non usa mai più memoria rispetto alla colonna sorgente…se non riesce a comprimerla la lascia come è  Vertipaq durante il processing di un tabella  Divide la tabella in colonne  Comprime ogni colonna con RLE  Obbiettivo 1 L’ordinamento delle colonne è il punto più importante per RLE (se ne occupa vertipaq ) buon ordinamento = buona compressione  Obbiettivo 2 : Se la dimensione della colonna in memoria è bassa lo scan sarà più veloce
  • 22. #sqlsat589February 25th, 2017 Dictionary encoding - 2 livello Conoscendo i possibili valori della stringa utilizzo il numero minimo di bit per rappresentarla. In questo caso 4 possibili valori bastano 2 bit. Creo il dizionario Quarter Q1 Q4 Q1 ... Q2 Q3 Q1 ... Q3 Q3 Q2 ... Q1 Q1 .... DISTINCT Indice Quarter 1 Q1 2 Q2 3 Q3 4 Q4 Quarter 1 1 1 ... 2 2 2 ... 3 3 3 ... 4 4 .... SOSTITUISCI RLE Quarter Count Lunghezza 1 1 400 2 400 400 3 800 100 4 900 100 xVelocity storage Con il dictionary encoding Vertipaq è datatyping independent. Non ha nessuna importanza il tipo dei campi che si utilizzano nelle viste per popolare il modello Indice Quarter 1 Q1 2 Q2 3 Q3 4 Q4 Versionecompressa Dizionario
  • 23. #sqlsat589February 25th, 2017 Conclusioni su RLE e Dictionary encoding  Una stringa nella tabella dei fatti (osceno) non ha più nessun prezzo grazie al dictionary encoding  Obbiettivo 1: Importa solo il numero di valori distinti delle colonne  Tanti valori distinti occupano più spazio (+ RAM) ed più lungo a fare analisi  Pochi valori distinti occupano poco spazio (- RAM) e tutte operazioni ridotte
  • 24. #sqlsat589February 25th, 2017  Long Scan Time: Spesso per aggregazioni semplici le query DAX fanno lo scan su una o piu colonne. Il costo di questa scan dipende dalla dimensione delle colonne che dipende dal numero di valori distinti e loro distribuzione  Large Cardinality: Un largo numero di valori univoci in una colonna può dare noia alla DISTINCTCOUNT  Alta frequenza di CallbackDataID: Un largo numero di chiamate dallo storage engine al formula engine possono influire pesantemente sulle performance  Large Materializzation: Se uno Storage Engine produce una grande datacache la sua generazione richiede tempo (allocamento di RAM) Cause dei bottlenecks nello storage engine
  • 26. #sqlsat589February 25th, 2017 Demo 0  La sum è sensibile alla dimensione perchè deve fare lo scan della tabella quindi deve fare lo scan di tutte le colonne  La distinctcount dipende dalla cardinalità  N.B. Ridurre il numero di valori distinti velocizza le query  Colonna Memoria (MB) Valori distinti SUM DISTINCTCOUNT Sales Amount 1,855,587,152 40,000 809 2023 TimeKey 1,237,296,936 86,400 526 2556
  • 27. #sqlsat589February 25th, 2017 Demo 1  Eseguiamo la seguente formula DAX  Genera un query plan che con due scansioni due coppie di Vertipaq Scan SQL Profiler DAX Studio
  • 28. #sqlsat589February 25th, 2017 Demo 1 – Perchè due query SE?  1° Vertiaq Scan estrae CalendarYear da Date e la somma di Sales Amount da Internet Sales. Usa solo SE perchè sono operazioni che sa fare  Se la prima query risolve tutto perchè c’è una 2° Internal Vertiaq Scan?  La seconda restituisce gli anni e la prima le vendite e anni e poi metto assieme con FE
  • 29. #sqlsat589February 25th, 2017 Demo 1 – Considerazioni sull’ottimizzazione  Recupera gli anni dalla tabella dei fatti  Che senso ha fare la scansione della tabella dei fatti per gli anni?  Secondo voi quale è la maniera più veloce per recuperare tutte le date?  Analizzando la tabella dei fatti (77.309.440 rows)  Analizzando la tabella della dimensione Date (3652 rows)
  • 30. #sqlsat589February 25th, 2017 Demo 2 – SUMMARIZE vs ADDCOLUMNS  Con la nuova query si azzera il tempo per recuperare l’anno SQL Profiler DAX Studio
  • 31. #sqlsat589February 25th, 2017 Demo 2 – SUMMARIZE vs ADDCOLUMNS  Con la SUMMURIZE al posto di VALUE peggioro le performance ma scrivo meno DAX  E se uso SUMMARIZECOLUMNS (Dax 2015) ?
  • 32. #sqlsat589February 25th, 2017  Una summarize dove aggreghiamo sia per anno che per colore.  2° Vertipaq Scan per recuperare anno e colore fa uno scan su tabella fatti Demo 3 – Problema SUMMARIZE con più colonne SQL Profiler DAX Studio
  • 33. #sqlsat589February 25th, 2017 Demo 3 – Soluzione  Utilizzamo la ADDCOLUMNS con CROSSJOIN per ottimizzare la formula  Le Vertipaq Scan aumentano da 2 a 3 perchè viene eseguita una Internal Vertipaq Scan secca sulla tabella prodotti e calendario SQL Profiler DAX Studio
  • 34. #sqlsat589February 25th, 2017  Con ROLLUP possiamo ottenere il venduto per anno e colore , il totale per anno e colore e il grand total per anno. Ci sono due modi di operare:  Generazione di più query SE per recuperare i sottototali e per il grand total (l’unica possibile)  Recuperare il dettaglio e poi aggregare all’interno di FE per (questo solo se sono sicuro che sono additive) Demo 4 – ROLLUP
  • 35. #sqlsat589February 25th, 2017 Demo 4 – ROLLUP  Come si vede il numero di query SE è aumentato di molto  la ROLLUP aumenta la complessità di (2N + 1) volte (N n° parametri) (subtotali su 2 livelli =>2n+1=5 scansioni, 3 livelli =>3n+1=7 scansioni...) SQL Profiler DAX Studio
  • 36. #sqlsat589February 25th, 2017  Esaminiamo la seguente query DAX  I callbackDataID sono richieste di aiuto di SE a FE in quanto non sa fare IF  e chiede a FE di eseguirlo. Funziona ma ci sono due problemi:  uno è multi-thread e l’altro no  si parla di elaborazione di FE e quindi non si usa la cache Demo 5 – CallbackDataID
  • 37. #sqlsat589February 25th, 2017 Demo 5 – CallbackDataID  Anche se uso DIVIDE ho sempre la callbackID anche se è un pò più veloce
  • 38. #sqlsat589February 25th, 2017 Demo 5 – CallbackDataID  Riscriviamo la formula per levare la CallBackDataID
  • 39. #sqlsat589February 25th, 2017  La SUMX non si comporta come una iterazione perchè viene eseguita direttamente da Vertipaq in quanto la sa gestire Demo 5 – CallbackDataID non avviene con le interazioni singole
  • 40. #sqlsat589February 25th, 2017  doppia iterazione genera un CallbackDataID Demo 5 – CallbackDataID avviene con le interazioni annidate
  • 41. #sqlsat589February 25th, 2017  Vogliamo ottenere i 50 prodotti che hanno vendite maggiori Demo 6 – Riduciamo la materializzazione Dobbiamo ridurre la dimensione della datacache che in questo caso è di 79 KB
  • 42. #sqlsat589February 25th, 2017  Dobbiamo ridurre la dimensione della Datacache Demo 6 – Riduciamo la materializzazione
  • 43. #sqlsat589February 25th, 2017  Capire come funzionano SE e FE  Ridurre FE, aumentare SE  Leggere i query plan rende possibile l’ottimizzazione  DAX non è facile da ottimizzare.... Ma è meglio che con MDX  Libro di riferimento da cui partire  https://www.sqlbi.com/books/the-definitive-guide-to-dax/  Link di riferimento per approfondire  http://www.sqlbi.com/wp-content/uploads/DAX-Query-Plans.pdf  http://www.sqlbi.com/wp-content/uploads/Understanding-Distinct-Count-in- DAX-Query-Plans.pdf Conclusioni