SlideShare a Scribd company logo
1 of 50
xVelocity in Deep 
Marco Pozzan 
twitter: @marcopozzan 
email: info@marcopozzan.it 
site: www.marcopozzan.it 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Sponsors 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Organizers 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Speaker info 
 MVP SQL Server 
 Presidente della community 1nn0va 
(www.innovazionefvg.net) 
 Project manager del reparto Business 
Intelligence presso CGN S.P.A. (www.cgn.it) 
 Docente ITS all’Università di Pordenone 
 Partecipo agli eventi community 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Agenda 
 Gestione delle query 
 Che cosa è xVelocity in-memory 
 Row vs Columnar storage 
 RLE e Dictionary Encoding 
 Uso memoria: memorizzazione, processing e 
query 
 Best practice 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Gestione delle query 
 Direct Query mode 
 Trasformazione da DAX a SQL 
 Query sul motore SQL Server 
 Molte limitazioni (solo connessione SQL, solo DAX no 
MDX, limiti DAX, no colonne calcolate, no security) 
 In Memory mode 
 Engine per elaborare formule DAX (formula engine 
DAX) 
 Storage Engine Vertipaq (xVelocity in-memory) 
 Sfrutta tutte le funzionalità di Tabular 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Gestione delle query 
DAX/MDX query 
Analysis 
Services 
2012 
Tabular 
Model 
DirectQuery 
Mode (Motore di 
query) 
In-Memory Mode 
(Motore di query) 
SQL Query 
Query 
Query 
Storage engine query 
Storage engine query 
Storage engine query 
 PROCESS = Lettura dalla sorgente dati 
 Vertipaq contiene il risultato del processing del 
database 
External 
Data 
Sources 
Process 
Vertipaq 
Storage 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Che cosa è xVelocity in-memory? 
 E’ un database in memoria (dati sono in memoria) 
 E’ basato su una metodologia relazionale 
 Database colonnare 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Come lavora un row storage 
Alloco spazio su disco 
(pagine) 
Id FirstName LastName BirthDate 
Marital 
Status 
Children 
1 Larry Gill 13/04/1977 00:00 M 1 
2 Geoffrey Gonzalez 06/02/1977 00:00 S 2 
3 Blake Collins 23/04/1975 00:00 M 0 
4 Alexa Watson 25/08/1977 00:00 S 0 
5 Jacquelyn Dominguez 27/09/1977 00:00 M 1 
6 Casey Gutierrez 17/12/1977 00:00 M 1 
7 Colleen Lu 17/07/1973 00:00 M 2 
8 Jeremiah Stewart 26/06/1979 00:00 S 1 
9 Leah Li 06/10/1976 00:00 S 0 
Id FirstName LastName BirthDate 
Marital 
Status 
Children 
1 Larry Gill 13/04/1977 00:00 M 1 
2 Geoffrey Gonzalez 06/02/1977 00:00 S 2 
3 Blake Collins 23/04/1975 00:00 M 0 
4 Alexa Watson 25/08/1977 00:00 S 0 
Alloco ancora spazio 
su disco perchè finito 
5 Jacquelyn Dominguez 27/09/1977 00:00 M 1 
6 Casey Gutierrez 17/12/1977 00:00 M 1 
7 Colleen Lu 17/07/1973 00:00 M 2 
8 Jeremiah Stewart 26/06/1979 00:00 S 1 
9 Leah Li 06/10/1976 00:00 S 0 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Caratteristiche di un row storage 
 SELECT * di una tabella 
 Legge tutta la tabella dalla prima all’ultima riga 
 SELECT SUM(children) della tabella 
 Legge tutta la tabella dalla prima all’ultima riga e poi 
si legge solo la colonna children per fare la somma 
 Prestazioni pessime per un dato piccolo devo fare 
tanto I/0 su disco che poi non serve 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Caratteristiche di un row storage 
 Il risultato della SELECT SUM(children) non cambia 
nemmeno se faccio I/O in memoria e non su disco 
 Trasferisco i dati dalla memoria alla cache della CPU 
dove si svolge il calcolo 
 La cache interna è molto limitata 
 Pessimo uso perché carico una grande parte di 
memoria per poi usarne un pezzettino 
 Ottengo comunque prestazioni peggiori rispetto al 
fatto di lavorare su dati più compatti (Problema) 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Soluzione con gli indici 
 Se devo fare spesso la SUM(children) 
 Creo un indice su children 
 La query richiede solo il campo children (l’indice 
copre la query), leggo solo l’indice e non tutta la 
tabella 
 L’indice contiene dati più compatti e mi aiuta per I/O 
 Gli indici in generale riducono il numero di colonne 
di una tabella e ottimizzano l’I/0 
Concetto di Column Storage 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Caratteristiche di un column storage 
 Portiamo il concetto di indice in memoria 
 Estremizziamo il concetto di indice 
Marital Status 
Id Id 
FirstName FirstName 
LastName 
BirthDate BirthDate 
Marital Status Children 
1 1 
Larry Larry 
Gill 
13/13/04/04/1977 1977 00:00:00 00 
M M 
1 
2 2 
Geoffrey Geoffrey 
Gonzalez 
06/06/02/02/1977 1977 00:00:00 00 
S S 
2 
3 3 
Blake Blake 
Collins 
23/23/04/04/1975 1975 00:00:00 00 
M M 
0 
4 4 
Alexa Alexa 
Watson 
25/25/08/08/1977 1977 00:00:00 00 
S S 
0 
5 5 
Jacquelyn Jacquelyn 
Dominguez 
27/27/09/09/1977 1977 00:00:00 00 
M M 
1 
6 6 
Casey Casey 
Gutierrez 
17/17/12/12/1977 1977 00:00:00 00 
M M 
1 
7 7 
Colleen Colleen 
Lu 
17/17/07/07/1973 1973 00:00:00 00 
M M 
2 
8 8 
Jeremiah Jeremiah 
Stewart 
26/26/06/06/1979 1979 00:00:00 00 
S S 
1 
9 9 
Leah Leah 
Li 
06/06/10/10/1976 1976 00:00:00 00 
S S 
0 
Un file per colonna 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Caratteristiche di un column storage 
 Faccio una SELECT SUM(children) della tabella 
 Non devo fare un indice 
 La colonna è già l’indice perché contiene solo 
children 
 Molto veloce 
 Faccio SELECT SUM(children) GROUP BY FirstName 
 Non è più così bello 
 Devo leggere due colonne: Children e FirstName 
 Devo poi unire il risultato pagando tempo di CPU 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Caratteristiche di un column storage 
 Rispetto alla row storage 
 più velocità se devo leggere una colonna 
 più velocità se leggo poche colonne 
 più lento se faccio SELECT * 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Column vs Row 
 Memorizzazione su colonna 
 Accesso veloce ad una singola colonna 
 Ho la necessità di materializzare le righe 
 Spendiamo CPU per ridurre I/0 (le CPU le possono 
fare più veloci o metterne tante ) 
 Memorizzazione per riga 
 Accesso veloce alla singola riga 
 Non necessita di materializzazione 
 Spendiamo l’I/O per ridurre la CPU (i dischi o la 
memoria non si possono fare più veloci ) 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Cambiare il modo di pensare (colonnare) 
 Siamo in un mondo in cui lo storage è fatto da una sola 
colonna . 
 Ci sono cose che si possono fare memorizzando i dati 
in colonna che sono più efficienti rispetto ai dati 
memorizzati su riga 
Sapete come funziona la compressione di SQL Server? 
 per riga (non fa grandi cose… pulizie spazi bianchi, ridurre 
caratteri unicode, ridurre i decimali …..) 
 per pagina (identifica all’interno della pagina parti uguali e 
le indicizza per poi comprimere la pagina creando un indice 
all’inizio) 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
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 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Run Length Encoding (RLE) - 1 livello 
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 
... 
Potrei anche decidere di 
togliere la colonna inizio 
e tenere solo la fine 
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. 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
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 
 Attenzione!!! L’ordinamento delle colonne deve 
essere lo stesso per ogni colonna perchè devo 
materializzare i dati delle varie colonne (se ne 
occupa vertipaq ) buon ordinamento = buona 
compressione 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Dictionary encoding - 2 livello 
 Più importante di RLE 
 Vediamo i passi per creare il Dictionary 
1. Vertipaq legge una colonna di tipo stringa 
2. Effettua il distinct della colonna 
3. Ogni valore stringa è associato ad un numero in un 
Dictionary 
4. Sostituisco i valori stringa nella colonna con i numeri 
del Dictionary 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Dictionary encoding - 2 livello 
Creo il 
dizionario 
DISTINCT 
Indice Quarter 
1 Q1 
2 Q2 
3 Q3 
4 Q4 
SOSTITUISCI 
Conoscendo i possibili valori della 
stringa utilizzo il numero minimo di 
bit per rappresentarla. In questo 
caso 4 possibili valori bastano 2 bit. 
Quarter 
Q1 
Q4 
Q1 
... 
Q2 
Q3 
Q1 
... 
Q3 
Q3 
Q2 
... 
Q1 
Q1 
.... 
Quarter 
1 
1 
1 
... 
2 
2 
2 
... 
3 
3 
3 
... 
4 
4 
.... 
RLE 
xVelocity storage 
Quarter Count Lunghezza 
1 1 400 
2 400 400 
3 800 100 
4 900 100 
Con il dictionary encoding Vertipaq è data typing 
independent. Non ha nessuna importanza il tipo dei campi 
che si utilizzano nelle viste per popolare il modello 
#sqlsatParma 
#sqlsat355 November 22nd, 2014 
Versione compressa 
Dizionario
Conclusioni su RLE e Dictionary encoding 
 Una stringa nella tabella (osceno) dei fatti non ha 
più nessun prezzo grazie al dictionary encoding 
 DOVETE vivere  pensando che Vertipaq memorizza i 
dati in questo modo. E’ fondamentale quando andrete a 
costruire un modello con Vertipaq 
 Importa solo il numero di valori distinti delle colonne 
 Tanti valori distinti occupano più spazio (+ RAM) 
ed più lungo fare analisi 
 Pochi valori distinti occupano poco spazio (- RAM) 
e tutte operazioni ridotte 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Conclusioni sulla compressione 
 Dictionary Encoding 
 Avviene quando è necessario: per una colonna con valori 
interi e con valori distinti molto alti conviene memorizzare il 
numero perché il dizionario sarebbe troppo grande 
 Rende le tabelle data type independent 
 RLE Encoding 
 Solo se i dati compressi sono più piccoli dell’originale 
 Dipende fortemente dall’ordine dei dati 
 SSAS sceglie il sorting migliore durante il process (10 s/milione di 
righe). Trovare stesso ordinamento per le colonne è difficile. 
Thomas Kejser: + 25% compressione con ordinamento sorgente 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Conclusioni sulla compressione 
 La compressione deriva dal fatto che abbiamo: 
 Column Store 
 Dictionary Encoding 
 RLE Encoding 
 Compressione: uso meno RAM e quindi più velocità e il 
modello riesce a stare nel server . Scansioni delle 
colonne sono più veloci 
 Il valore di compressione che ci possiamo aspettare è…. 
 Non lo sa nessuno ma la risposta commerciale è 10x 
anche si può arrivare a 50x o a 2x 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Segmentation 
 Fino ad ora abbiamo visto come Vertipaq processa e 
comprime una colonna 
 Cosa succede con la tabella intera? 
 In realtà Vertipaq non processa tutta la tabella prima di 
fare la compressione perché non avrebbe abbastanza 
memoria 
 Si usa la tecnica della segmentation 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Segmentation 
 Ogni tabella è divisa in segmenti (dimensione variabile) 
 8 milioni di righe per ogni segmento in SSAS 
 1 milione di righe in PowerPivot 
 C’è un dizionario globale per la tabella 
 Bit-sizing (forma compatta del dizionario) è locale ad 
ogni segmento 
 Ci sono delle DMV per avere informazione sui segmenti 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Segmentation cycle 
Legge il segmento 
Genera o aggiorna il dizionario 
globale 
Genera un dizionario locale al 
segmento bit-sizing 
Comprime tutto e memorizza e 
passa al secondo segmento 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Importanza della Segmentation 
 Viene usata per lavorare su un insieme ridotto di dati per la 
compressione ( 1 o 8 millioni di righe) 
 Viene usata come base per il parallelismo all’interno delle 
query 
 Quando Vertipaq risolve una query usa un thread per 
ogni segmento della tabella (per fare la scansione) 
 Se ho meno di 8 milioni userà un solo thread perché è 
antipoduttivo usarne di più 
 Se ho 80 milioni di righe userà 10 thread su 10 core 
separati (ideale ma impensabile per conflitto sul bus) 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Segmentation 
 Fasi della segmentazione durante il processing 
Legge e crea i 
dizionari del segmento 
N 
Legge e crea i 
dizionari del segmento 
N + 1 
Comprime 
segmento N 
Comprime 
segmento N+1 
Crea colonne calcolate, 
gerarchie, relazioni e 
tutte le strutture dati 
Fine lettura dati del 
modello 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Segmentation: caso speciale del 3 segmento 
 Vertipaq cerca di ridurre il numero di segmenti da caricare 
 fa un tentativo di leggere i primi due segmenti assieme (come 
fosse unico). Se ci sono 12 milioni di righe è inutile leggerli in due 
passi e legge direttamente 16 milioni di righe (primo segmento) 
altrimenti segmenta normalmente 
Legge e crea i 
dizionari del 
segmento 1 e 2 
Legge e crea i 
dizionari del segmento 
3 
Comprime 
segmento 1 
Comprime 
segmento 2 
Crea colonne calcolate, 
gerarchie, relazioni e 
tutte le strutture dati 
Comprime 
segmento 3 
Fine lettura dati del 
modello 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Configurazione della segmentazione 
 La configurazione e a livello di istanza 
 DefaultSegmentRowCount (0 = default) 
 ProcessingTimeboxSecPerMRow per decidere il tempo entro al 
quale deve ordinare 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Uso memoria durante il processing 
 Ogni tabella è processata sequenzialmente (anche se 
partizionata) 
 Non ci sono parallelismi sulla partizione come SSAS 
 Ogni tabella è divisa in segmenti 
 Per ogni segmento 
 Caricamento 
 Compressione (un thread per colonna: parallelismo) 
 Memorizzazione 
 Più tabelle possono essere caricate in parallelo 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Uso memoria durante memorizzazione 
 L’uso della memoria nella memorizzazione dipende da: 
 Numero di colonne 
 Cardinalità di ogni colonna (valori distinct) 
 Tipo di dato (varia il dizionario) 
 Numero di righe 
 Non ci sono formule per calcolare lo spazio occupato da 
una tabella. L’unico modo è creare un prototipo!!! 
 Attenzione ad avere un prototipo con dati veri  i dati 
nascosti sfalsano la distribuzione dei dati. 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Uso memoria durante le query 
 La cache richiede memoria 
 Le query semplici richiedono un po’ di memoria 
 Le query complesse richiedono molta memoria 
 Fare spooling per valori temporanei 
 Materializzare un dataset ( se faccio una query su più 
colonne alla fine devo unire i risultati ) 
 Problema: in quanto molte volte può capitare che 
la versione materializzata sia più grande della 
tabella originale 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Materialization 
 Se vogliamo eseguire su un database colonnare la 
seguente query: 
SELECT SUM(num730) AS N730,[COD_Ufficio] 
FROM [dbo].[Dichiarazioni730] 
WHERE [COD_Utente] = 345 AND [Tipo730] = 1 
GROUP BY [COD_Ufficio] 
Tipo730 
1 
2 
1 
1 
Cod_Ufficio 
4555 
2345 
6545 
444 
COD_Utente 
345 
1678 
345 
100 
 Ci sono diverse tecniche ma agli estremi ci sono: 
 Early Materialization 
 Late Materializzation 
num730 
234 
100 
400 
3 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Early materialization 
Tipo730 
1 
2 
1 
1 
Cod_Ufficio 
4555 
2345 
4555 
444 
num730 
234 
100 
400 
3 
COD_Utente 
345 
1678 
345 
100 
Ricomponiamo il row store 
(Materializzo) 
345 1 4555 234 
1678 2 2345 100 
345 1 4555 400 
100 1 444 3 
SELECT SUM(num730) AS N730,[COD_Ufficio] 
FROM [dbo].[Dichiarazioni730] 
WHERE [COD_Utente] = 345 AND [Tipo730] = 1 
GROUP BY [COD_Ufficio] 
La fregatura è che faccio tanto 
lavoro per comprimere in 
colonne separate e poi devo 
riunire tutto. Uso tanta 
memoria se faccio select * 
Applico la where 
345 1 4555 234 
345 1 4555 400 
Proiezione per num730 e cod_ufficio 
4555 234 
4555 400 
Sommo 
4555 634 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Late materializzation 
Tipo730 
Tipo730 
1 
2 
1 
1 
Cod_Ufficio 
4555 
2345 
4555 
444 
num730 
234 
100 
400 
3 
COD_COD_Utente 
345 
1678 
345 
100 
SELECT SUM(num730) AS N730,[COD_Ufficio] 
FROM [dbo].[Dichiarazioni730] 
WHERE [COD_Utente] = 345 AND [Tipo730] = 1 
GROUP BY [COD_Ufficio] 
Bitmap 
1 
0 
1 
0 
Applico la clausola 
where sulle due 
colonne separate 
Materializzo 
4555 234 
4555 400 
Sommo 
4555 634 
Bitmap 
1 
0 
1 
1 
And 
Bitmap 
1 
0 
1 
0 
Cod_Ufficio 
4555 
2345 
6545 
444 
num730 
234 
100 
400 
3 
Applico la bitmap 
Cod_Ufficio 
4555 
4555 
num730 
234 
400 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Quando avviene la materializzazione 
 La materializzazione avviene per Join complessi 
 La materializzazione avviene per iterazioni complesse 
 Durante il salvataggio di dati temporanei 
Praticamente devo sempre materializzare 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Quanto spazio uso per il mio modello? 
 Nella directory dei dati, c’è un folder per ogni database 
 ..Microsoft SQL ServerMSAS11.MSSQLSERVEROLAPData 
 AdventureWorks Tabular Model SQL 2012....... 
 Tipo di file ed estensioni 
 Dictionary: .DICTIONARY 
 Data: .IDF 
 Index: .IDF (POS_TO_ID, ID_TO_POS) 
 Relationship: GUID + .HDX 
 Hierachies: .JDF 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Quanto spazio uso per il mio modello? 
 Ci sono anche delle DMV per estrarre le informazioni sullo 
stato del database di Tabular (ma sono complicate) 
 Ritorna tutte le possibili DMV 
 SELECT * FROM $SYSTEM.DISCOVER_SCHEMA_ROWSETS 
 Ritorna la memoria utilizzata da tutti gli oggetti 
 SELECT * FROM $SYSTEM.DISCOVER_OBJECT_MEMORY_USAGE 
 Dettagli delle singole colonne 
 SELECT * FROM $SYSTEM.DISCOVER_STORAGE_TABLE_COLUMNS 
 Dettagli sui segmenti 
 SELECT * FROM 
$SYSTEM.DISCOVER_STORAGE_TABLE_COLUMN_SEGMENT 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Quanto spazio uso per il mio modello? 
 In alternativa alle DMV usate il PowerPivot di Kasper De 
Jonge. 
 Si apre un foglio excel in cui da powerpivot interrogo le 
DMV su un istanza di analisys services 
http://www.powerpivotblog.nl/what-is-using-all-that-memory-on- 
my-analysis-server-instance/ 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Best Practice (ridurre il dictionary) 
 Ridurre la lunghezza delle stringhe 
 Ridurre il numero di valori distinti 
 Dividere DateTime in due colonne (troppi valori distinti) 
 Date 
 Time 
 Deve essere fissata una precisione per i valori floating point 
 76.201 diventa 76.2 
 Cercate di risolvere tutto a livello di sorgente dati e non in 
colonne calcolate (esempio con le viste) 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Best Practice (ridurre dimensioni tabelle) 
 Attenzione alle Junk Dimensions. Faccio la cross join 
della distinct di questi valori junk e li metto nella tabella 
junk e poi ci punto dentro con un intero 
 Meglio + campi con pochi valori distinti sulla tabella 
dei fatti che uno che è il cross join dei valori distinti 
 Se poi ho dimensioni con solo Id e descrizione è 
meglio memorizzare la descrizione nei fatti 
 Descrizione occupa come l’Id nei fatti 
 Non pago un join a query time 
 Ho un tabella in meno da memorizzare che è inutile 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Best Practice (ridurre dimensioni tabelle) 
 Evitare risultati parziali in colonne calcolate 
 essi tendono ad avere molti valori distinti 
 aumentano il numero di colonne 
 Rimuovere le colonne non utilizzate 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Best Practice dimensioni degeneri 
 Problema -> Memorizzare un ID per il DrillThrought nei 
report è costoso (sacco di valori distinti) 
 Un solo valore per ogni riga 
 un grande dizionario per grandi tabelle 
 Soluzione -> Splittare in più colonne 
 Tabella di 100 milioni di righe. N° di fattura che è 
dato da anno + progressivo. Lo divido in due o più 
colonne. Le colonne hanno un dizionario più piccolo. 
 Se poi lo devo visualizzare sul report rimaterializzare 
lo faccio su un sottoinsieme di righe . 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Workbook Optimizer 
 esamina la composizione del modello di dati 
all'interno della vostra cartella di lavoro di 
PowerPivot 
http://www.microsoft.com/en-us/download/details.aspx?id=38793 
 vede se i dati in essa contenuti possono 
occupare meno spazio 
 vede se possibile fare una migliore 
compressione 
 Non è il massimo deve migliorare molto 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
Conclusioni su xVelocity 
 Ha degli algoritmi di compressione molto efficienti 
 Molto veloce sulle colonne singole 
 L’accesso a più colonne richiede la materializzazione 
 Metodo di memorizzazione diverso dai classici 
database 
 Richiede un cambiamento di mentalità 
 Tentate di pensare a colonne singole 
 Tutte queste caratteristiche si riflettono in DAX. 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
DEMO 
 Testiamo tutto quello fino a qui imparato su un 
caso reale di foglio excel bello grande. 
#sqlsatParma 
#sqlsat355 November 22nd, 2014
THANKS! 
#sqlsatParma 
#sqlsat355 
#sqlsatParma 
#sqlsat355 November 22nd, 2014

More Related Content

Similar to xVelocity in Deep

DEFTCON 2014 – Luigi Ranzato - Windows Registry Artifacts: "Most Recently Use...
DEFTCON 2014 – Luigi Ranzato - Windows Registry Artifacts: "Most Recently Use...DEFTCON 2014 – Luigi Ranzato - Windows Registry Artifacts: "Most Recently Use...
DEFTCON 2014 – Luigi Ranzato - Windows Registry Artifacts: "Most Recently Use...Deft Association
 
Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1guest5c2d35b
 
Presentazione Nuvola Vertica Full
Presentazione Nuvola Vertica FullPresentazione Nuvola Vertica Full
Presentazione Nuvola Vertica FullAlberto.F
 
Presentazione Nuvola Vertica F
Presentazione Nuvola Vertica FPresentazione Nuvola Vertica F
Presentazione Nuvola Vertica FAlberto.F
 
Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Alberto.F
 
Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Alberto.F
 
Presentazione Nuvola Vertica Full New
Presentazione Nuvola Vertica Full NewPresentazione Nuvola Vertica Full New
Presentazione Nuvola Vertica Full NewAlberto.F
 
[ITA] Sql Saturday 355 in Parma - New SQL Server databases under source control
[ITA] Sql Saturday 355 in Parma - New SQL Server databases under source control[ITA] Sql Saturday 355 in Parma - New SQL Server databases under source control
[ITA] Sql Saturday 355 in Parma - New SQL Server databases under source controlAlessandro Alpi
 

Similar to xVelocity in Deep (8)

DEFTCON 2014 – Luigi Ranzato - Windows Registry Artifacts: "Most Recently Use...
DEFTCON 2014 – Luigi Ranzato - Windows Registry Artifacts: "Most Recently Use...DEFTCON 2014 – Luigi Ranzato - Windows Registry Artifacts: "Most Recently Use...
DEFTCON 2014 – Luigi Ranzato - Windows Registry Artifacts: "Most Recently Use...
 
Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1
 
Presentazione Nuvola Vertica Full
Presentazione Nuvola Vertica FullPresentazione Nuvola Vertica Full
Presentazione Nuvola Vertica Full
 
Presentazione Nuvola Vertica F
Presentazione Nuvola Vertica FPresentazione Nuvola Vertica F
Presentazione Nuvola Vertica F
 
Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1Presentazione Nuvola Vertica Full New1
Presentazione Nuvola Vertica Full New1
 
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
 
[ITA] Sql Saturday 355 in Parma - New SQL Server databases under source control
[ITA] Sql Saturday 355 in Parma - New SQL Server databases under source control[ITA] Sql Saturday 355 in Parma - New SQL Server databases under source control
[ITA] Sql Saturday 355 in Parma - New SQL Server databases under source control
 

More from Marco Pozzan

Metadata Driven Pipeline with Microsoft Fabric
Metadata Driven Pipeline  with Microsoft FabricMetadata Driven Pipeline  with Microsoft Fabric
Metadata Driven Pipeline with Microsoft FabricMarco Pozzan
 
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 lakehouseMarco Pozzan
 
Data modelling for Power BI
Data modelling for Power BIData modelling for Power BI
Data modelling for Power BIMarco Pozzan
 
SlideModellingDataSat.pdf
SlideModellingDataSat.pdfSlideModellingDataSat.pdf
SlideModellingDataSat.pdfMarco Pozzan
 
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 SynapseMarco Pozzan
 
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-serviceMarco Pozzan
 
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 modelMarco Pozzan
 
REAL TIME ANALYTICS INFRASTRUCTURE WITH AZURE
REAL TIME ANALYTICS INFRASTRUCTURE WITH AZUREREAL TIME ANALYTICS INFRASTRUCTURE WITH AZURE
REAL TIME ANALYTICS INFRASTRUCTURE WITH AZUREMarco Pozzan
 
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 biMarco Pozzan
 
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 contextMarco Pozzan
 
Azure saturday pn 2018
Azure saturday pn 2018Azure saturday pn 2018
Azure saturday pn 2018Marco Pozzan
 
Power B: Cleaning data
Power B: Cleaning dataPower B: Cleaning data
Power B: Cleaning dataMarco Pozzan
 
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)Marco Pozzan
 
Power BI and business application platform
Power BI and business application platformPower BI and business application platform
Power BI and business application platformMarco Pozzan
 

More from 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
 
Power bi + Flow
Power bi + FlowPower bi + Flow
Power bi + Flow
 
Power BI
Power BIPower BI
Power BI
 
Power query
Power queryPower query
Power query
 

xVelocity in Deep

  • 1. xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site: www.marcopozzan.it #sqlsatParma #sqlsat355 November 22nd, 2014
  • 2. Sponsors #sqlsatParma #sqlsat355 November 22nd, 2014
  • 4. Speaker info  MVP SQL Server  Presidente della community 1nn0va (www.innovazionefvg.net)  Project manager del reparto Business Intelligence presso CGN S.P.A. (www.cgn.it)  Docente ITS all’Università di Pordenone  Partecipo agli eventi community #sqlsatParma #sqlsat355 November 22nd, 2014
  • 5. Agenda  Gestione delle query  Che cosa è xVelocity in-memory  Row vs Columnar storage  RLE e Dictionary Encoding  Uso memoria: memorizzazione, processing e query  Best practice #sqlsatParma #sqlsat355 November 22nd, 2014
  • 6. Gestione delle query  Direct Query mode  Trasformazione da DAX a SQL  Query sul motore SQL Server  Molte limitazioni (solo connessione SQL, solo DAX no MDX, limiti DAX, no colonne calcolate, no security)  In Memory mode  Engine per elaborare formule DAX (formula engine DAX)  Storage Engine Vertipaq (xVelocity in-memory)  Sfrutta tutte le funzionalità di Tabular #sqlsatParma #sqlsat355 November 22nd, 2014
  • 7. Gestione delle query DAX/MDX query Analysis Services 2012 Tabular Model DirectQuery Mode (Motore di query) In-Memory Mode (Motore di query) SQL Query Query Query Storage engine query Storage engine query Storage engine query  PROCESS = Lettura dalla sorgente dati  Vertipaq contiene il risultato del processing del database External Data Sources Process Vertipaq Storage #sqlsatParma #sqlsat355 November 22nd, 2014
  • 8. Che cosa è xVelocity in-memory?  E’ un database in memoria (dati sono in memoria)  E’ basato su una metodologia relazionale  Database colonnare #sqlsatParma #sqlsat355 November 22nd, 2014
  • 9. Come lavora un row storage Alloco spazio su disco (pagine) Id FirstName LastName BirthDate Marital Status Children 1 Larry Gill 13/04/1977 00:00 M 1 2 Geoffrey Gonzalez 06/02/1977 00:00 S 2 3 Blake Collins 23/04/1975 00:00 M 0 4 Alexa Watson 25/08/1977 00:00 S 0 5 Jacquelyn Dominguez 27/09/1977 00:00 M 1 6 Casey Gutierrez 17/12/1977 00:00 M 1 7 Colleen Lu 17/07/1973 00:00 M 2 8 Jeremiah Stewart 26/06/1979 00:00 S 1 9 Leah Li 06/10/1976 00:00 S 0 Id FirstName LastName BirthDate Marital Status Children 1 Larry Gill 13/04/1977 00:00 M 1 2 Geoffrey Gonzalez 06/02/1977 00:00 S 2 3 Blake Collins 23/04/1975 00:00 M 0 4 Alexa Watson 25/08/1977 00:00 S 0 Alloco ancora spazio su disco perchè finito 5 Jacquelyn Dominguez 27/09/1977 00:00 M 1 6 Casey Gutierrez 17/12/1977 00:00 M 1 7 Colleen Lu 17/07/1973 00:00 M 2 8 Jeremiah Stewart 26/06/1979 00:00 S 1 9 Leah Li 06/10/1976 00:00 S 0 #sqlsatParma #sqlsat355 November 22nd, 2014
  • 10. Caratteristiche di un row storage  SELECT * di una tabella  Legge tutta la tabella dalla prima all’ultima riga  SELECT SUM(children) della tabella  Legge tutta la tabella dalla prima all’ultima riga e poi si legge solo la colonna children per fare la somma  Prestazioni pessime per un dato piccolo devo fare tanto I/0 su disco che poi non serve #sqlsatParma #sqlsat355 November 22nd, 2014
  • 11. Caratteristiche di un row storage  Il risultato della SELECT SUM(children) non cambia nemmeno se faccio I/O in memoria e non su disco  Trasferisco i dati dalla memoria alla cache della CPU dove si svolge il calcolo  La cache interna è molto limitata  Pessimo uso perché carico una grande parte di memoria per poi usarne un pezzettino  Ottengo comunque prestazioni peggiori rispetto al fatto di lavorare su dati più compatti (Problema) #sqlsatParma #sqlsat355 November 22nd, 2014
  • 12. Soluzione con gli indici  Se devo fare spesso la SUM(children)  Creo un indice su children  La query richiede solo il campo children (l’indice copre la query), leggo solo l’indice e non tutta la tabella  L’indice contiene dati più compatti e mi aiuta per I/O  Gli indici in generale riducono il numero di colonne di una tabella e ottimizzano l’I/0 Concetto di Column Storage #sqlsatParma #sqlsat355 November 22nd, 2014
  • 13. Caratteristiche di un column storage  Portiamo il concetto di indice in memoria  Estremizziamo il concetto di indice Marital Status Id Id FirstName FirstName LastName BirthDate BirthDate Marital Status Children 1 1 Larry Larry Gill 13/13/04/04/1977 1977 00:00:00 00 M M 1 2 2 Geoffrey Geoffrey Gonzalez 06/06/02/02/1977 1977 00:00:00 00 S S 2 3 3 Blake Blake Collins 23/23/04/04/1975 1975 00:00:00 00 M M 0 4 4 Alexa Alexa Watson 25/25/08/08/1977 1977 00:00:00 00 S S 0 5 5 Jacquelyn Jacquelyn Dominguez 27/27/09/09/1977 1977 00:00:00 00 M M 1 6 6 Casey Casey Gutierrez 17/17/12/12/1977 1977 00:00:00 00 M M 1 7 7 Colleen Colleen Lu 17/17/07/07/1973 1973 00:00:00 00 M M 2 8 8 Jeremiah Jeremiah Stewart 26/26/06/06/1979 1979 00:00:00 00 S S 1 9 9 Leah Leah Li 06/06/10/10/1976 1976 00:00:00 00 S S 0 Un file per colonna #sqlsatParma #sqlsat355 November 22nd, 2014
  • 14. Caratteristiche di un column storage  Faccio una SELECT SUM(children) della tabella  Non devo fare un indice  La colonna è già l’indice perché contiene solo children  Molto veloce  Faccio SELECT SUM(children) GROUP BY FirstName  Non è più così bello  Devo leggere due colonne: Children e FirstName  Devo poi unire il risultato pagando tempo di CPU #sqlsatParma #sqlsat355 November 22nd, 2014
  • 15. Caratteristiche di un column storage  Rispetto alla row storage  più velocità se devo leggere una colonna  più velocità se leggo poche colonne  più lento se faccio SELECT * #sqlsatParma #sqlsat355 November 22nd, 2014
  • 16. Column vs Row  Memorizzazione su colonna  Accesso veloce ad una singola colonna  Ho la necessità di materializzare le righe  Spendiamo CPU per ridurre I/0 (le CPU le possono fare più veloci o metterne tante )  Memorizzazione per riga  Accesso veloce alla singola riga  Non necessita di materializzazione  Spendiamo l’I/O per ridurre la CPU (i dischi o la memoria non si possono fare più veloci ) #sqlsatParma #sqlsat355 November 22nd, 2014
  • 17. Cambiare il modo di pensare (colonnare)  Siamo in un mondo in cui lo storage è fatto da una sola colonna .  Ci sono cose che si possono fare memorizzando i dati in colonna che sono più efficienti rispetto ai dati memorizzati su riga Sapete come funziona la compressione di SQL Server?  per riga (non fa grandi cose… pulizie spazi bianchi, ridurre caratteri unicode, ridurre i decimali …..)  per pagina (identifica all’interno della pagina parti uguali e le indicizza per poi comprimere la pagina creando un indice all’inizio) #sqlsatParma #sqlsat355 November 22nd, 2014
  • 18. 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 #sqlsatParma #sqlsat355 November 22nd, 2014
  • 19. Run Length Encoding (RLE) - 1 livello 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 ... Potrei anche decidere di togliere la colonna inizio e tenere solo la fine 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. #sqlsatParma #sqlsat355 November 22nd, 2014
  • 20. 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  Attenzione!!! L’ordinamento delle colonne deve essere lo stesso per ogni colonna perchè devo materializzare i dati delle varie colonne (se ne occupa vertipaq ) buon ordinamento = buona compressione #sqlsatParma #sqlsat355 November 22nd, 2014
  • 21. Dictionary encoding - 2 livello  Più importante di RLE  Vediamo i passi per creare il Dictionary 1. Vertipaq legge una colonna di tipo stringa 2. Effettua il distinct della colonna 3. Ogni valore stringa è associato ad un numero in un Dictionary 4. Sostituisco i valori stringa nella colonna con i numeri del Dictionary #sqlsatParma #sqlsat355 November 22nd, 2014
  • 22. Dictionary encoding - 2 livello Creo il dizionario DISTINCT Indice Quarter 1 Q1 2 Q2 3 Q3 4 Q4 SOSTITUISCI Conoscendo i possibili valori della stringa utilizzo il numero minimo di bit per rappresentarla. In questo caso 4 possibili valori bastano 2 bit. Quarter Q1 Q4 Q1 ... Q2 Q3 Q1 ... Q3 Q3 Q2 ... Q1 Q1 .... Quarter 1 1 1 ... 2 2 2 ... 3 3 3 ... 4 4 .... RLE xVelocity storage Quarter Count Lunghezza 1 1 400 2 400 400 3 800 100 4 900 100 Con il dictionary encoding Vertipaq è data typing independent. Non ha nessuna importanza il tipo dei campi che si utilizzano nelle viste per popolare il modello #sqlsatParma #sqlsat355 November 22nd, 2014 Versione compressa Dizionario
  • 23. Conclusioni su RLE e Dictionary encoding  Una stringa nella tabella (osceno) dei fatti non ha più nessun prezzo grazie al dictionary encoding  DOVETE vivere  pensando che Vertipaq memorizza i dati in questo modo. E’ fondamentale quando andrete a costruire un modello con Vertipaq  Importa solo il numero di valori distinti delle colonne  Tanti valori distinti occupano più spazio (+ RAM) ed più lungo fare analisi  Pochi valori distinti occupano poco spazio (- RAM) e tutte operazioni ridotte #sqlsatParma #sqlsat355 November 22nd, 2014
  • 24. Conclusioni sulla compressione  Dictionary Encoding  Avviene quando è necessario: per una colonna con valori interi e con valori distinti molto alti conviene memorizzare il numero perché il dizionario sarebbe troppo grande  Rende le tabelle data type independent  RLE Encoding  Solo se i dati compressi sono più piccoli dell’originale  Dipende fortemente dall’ordine dei dati  SSAS sceglie il sorting migliore durante il process (10 s/milione di righe). Trovare stesso ordinamento per le colonne è difficile. Thomas Kejser: + 25% compressione con ordinamento sorgente #sqlsatParma #sqlsat355 November 22nd, 2014
  • 25. Conclusioni sulla compressione  La compressione deriva dal fatto che abbiamo:  Column Store  Dictionary Encoding  RLE Encoding  Compressione: uso meno RAM e quindi più velocità e il modello riesce a stare nel server . Scansioni delle colonne sono più veloci  Il valore di compressione che ci possiamo aspettare è….  Non lo sa nessuno ma la risposta commerciale è 10x anche si può arrivare a 50x o a 2x #sqlsatParma #sqlsat355 November 22nd, 2014
  • 26. Segmentation  Fino ad ora abbiamo visto come Vertipaq processa e comprime una colonna  Cosa succede con la tabella intera?  In realtà Vertipaq non processa tutta la tabella prima di fare la compressione perché non avrebbe abbastanza memoria  Si usa la tecnica della segmentation #sqlsatParma #sqlsat355 November 22nd, 2014
  • 27. Segmentation  Ogni tabella è divisa in segmenti (dimensione variabile)  8 milioni di righe per ogni segmento in SSAS  1 milione di righe in PowerPivot  C’è un dizionario globale per la tabella  Bit-sizing (forma compatta del dizionario) è locale ad ogni segmento  Ci sono delle DMV per avere informazione sui segmenti #sqlsatParma #sqlsat355 November 22nd, 2014
  • 28. Segmentation cycle Legge il segmento Genera o aggiorna il dizionario globale Genera un dizionario locale al segmento bit-sizing Comprime tutto e memorizza e passa al secondo segmento #sqlsatParma #sqlsat355 November 22nd, 2014
  • 29. Importanza della Segmentation  Viene usata per lavorare su un insieme ridotto di dati per la compressione ( 1 o 8 millioni di righe)  Viene usata come base per il parallelismo all’interno delle query  Quando Vertipaq risolve una query usa un thread per ogni segmento della tabella (per fare la scansione)  Se ho meno di 8 milioni userà un solo thread perché è antipoduttivo usarne di più  Se ho 80 milioni di righe userà 10 thread su 10 core separati (ideale ma impensabile per conflitto sul bus) #sqlsatParma #sqlsat355 November 22nd, 2014
  • 30. Segmentation  Fasi della segmentazione durante il processing Legge e crea i dizionari del segmento N Legge e crea i dizionari del segmento N + 1 Comprime segmento N Comprime segmento N+1 Crea colonne calcolate, gerarchie, relazioni e tutte le strutture dati Fine lettura dati del modello #sqlsatParma #sqlsat355 November 22nd, 2014
  • 31. Segmentation: caso speciale del 3 segmento  Vertipaq cerca di ridurre il numero di segmenti da caricare  fa un tentativo di leggere i primi due segmenti assieme (come fosse unico). Se ci sono 12 milioni di righe è inutile leggerli in due passi e legge direttamente 16 milioni di righe (primo segmento) altrimenti segmenta normalmente Legge e crea i dizionari del segmento 1 e 2 Legge e crea i dizionari del segmento 3 Comprime segmento 1 Comprime segmento 2 Crea colonne calcolate, gerarchie, relazioni e tutte le strutture dati Comprime segmento 3 Fine lettura dati del modello #sqlsatParma #sqlsat355 November 22nd, 2014
  • 32. Configurazione della segmentazione  La configurazione e a livello di istanza  DefaultSegmentRowCount (0 = default)  ProcessingTimeboxSecPerMRow per decidere il tempo entro al quale deve ordinare #sqlsatParma #sqlsat355 November 22nd, 2014
  • 33. Uso memoria durante il processing  Ogni tabella è processata sequenzialmente (anche se partizionata)  Non ci sono parallelismi sulla partizione come SSAS  Ogni tabella è divisa in segmenti  Per ogni segmento  Caricamento  Compressione (un thread per colonna: parallelismo)  Memorizzazione  Più tabelle possono essere caricate in parallelo #sqlsatParma #sqlsat355 November 22nd, 2014
  • 34. Uso memoria durante memorizzazione  L’uso della memoria nella memorizzazione dipende da:  Numero di colonne  Cardinalità di ogni colonna (valori distinct)  Tipo di dato (varia il dizionario)  Numero di righe  Non ci sono formule per calcolare lo spazio occupato da una tabella. L’unico modo è creare un prototipo!!!  Attenzione ad avere un prototipo con dati veri  i dati nascosti sfalsano la distribuzione dei dati. #sqlsatParma #sqlsat355 November 22nd, 2014
  • 35. Uso memoria durante le query  La cache richiede memoria  Le query semplici richiedono un po’ di memoria  Le query complesse richiedono molta memoria  Fare spooling per valori temporanei  Materializzare un dataset ( se faccio una query su più colonne alla fine devo unire i risultati )  Problema: in quanto molte volte può capitare che la versione materializzata sia più grande della tabella originale #sqlsatParma #sqlsat355 November 22nd, 2014
  • 36. Materialization  Se vogliamo eseguire su un database colonnare la seguente query: SELECT SUM(num730) AS N730,[COD_Ufficio] FROM [dbo].[Dichiarazioni730] WHERE [COD_Utente] = 345 AND [Tipo730] = 1 GROUP BY [COD_Ufficio] Tipo730 1 2 1 1 Cod_Ufficio 4555 2345 6545 444 COD_Utente 345 1678 345 100  Ci sono diverse tecniche ma agli estremi ci sono:  Early Materialization  Late Materializzation num730 234 100 400 3 #sqlsatParma #sqlsat355 November 22nd, 2014
  • 37. Early materialization Tipo730 1 2 1 1 Cod_Ufficio 4555 2345 4555 444 num730 234 100 400 3 COD_Utente 345 1678 345 100 Ricomponiamo il row store (Materializzo) 345 1 4555 234 1678 2 2345 100 345 1 4555 400 100 1 444 3 SELECT SUM(num730) AS N730,[COD_Ufficio] FROM [dbo].[Dichiarazioni730] WHERE [COD_Utente] = 345 AND [Tipo730] = 1 GROUP BY [COD_Ufficio] La fregatura è che faccio tanto lavoro per comprimere in colonne separate e poi devo riunire tutto. Uso tanta memoria se faccio select * Applico la where 345 1 4555 234 345 1 4555 400 Proiezione per num730 e cod_ufficio 4555 234 4555 400 Sommo 4555 634 #sqlsatParma #sqlsat355 November 22nd, 2014
  • 38. Late materializzation Tipo730 Tipo730 1 2 1 1 Cod_Ufficio 4555 2345 4555 444 num730 234 100 400 3 COD_COD_Utente 345 1678 345 100 SELECT SUM(num730) AS N730,[COD_Ufficio] FROM [dbo].[Dichiarazioni730] WHERE [COD_Utente] = 345 AND [Tipo730] = 1 GROUP BY [COD_Ufficio] Bitmap 1 0 1 0 Applico la clausola where sulle due colonne separate Materializzo 4555 234 4555 400 Sommo 4555 634 Bitmap 1 0 1 1 And Bitmap 1 0 1 0 Cod_Ufficio 4555 2345 6545 444 num730 234 100 400 3 Applico la bitmap Cod_Ufficio 4555 4555 num730 234 400 #sqlsatParma #sqlsat355 November 22nd, 2014
  • 39. Quando avviene la materializzazione  La materializzazione avviene per Join complessi  La materializzazione avviene per iterazioni complesse  Durante il salvataggio di dati temporanei Praticamente devo sempre materializzare #sqlsatParma #sqlsat355 November 22nd, 2014
  • 40. Quanto spazio uso per il mio modello?  Nella directory dei dati, c’è un folder per ogni database  ..Microsoft SQL ServerMSAS11.MSSQLSERVEROLAPData  AdventureWorks Tabular Model SQL 2012.......  Tipo di file ed estensioni  Dictionary: .DICTIONARY  Data: .IDF  Index: .IDF (POS_TO_ID, ID_TO_POS)  Relationship: GUID + .HDX  Hierachies: .JDF #sqlsatParma #sqlsat355 November 22nd, 2014
  • 41. Quanto spazio uso per il mio modello?  Ci sono anche delle DMV per estrarre le informazioni sullo stato del database di Tabular (ma sono complicate)  Ritorna tutte le possibili DMV  SELECT * FROM $SYSTEM.DISCOVER_SCHEMA_ROWSETS  Ritorna la memoria utilizzata da tutti gli oggetti  SELECT * FROM $SYSTEM.DISCOVER_OBJECT_MEMORY_USAGE  Dettagli delle singole colonne  SELECT * FROM $SYSTEM.DISCOVER_STORAGE_TABLE_COLUMNS  Dettagli sui segmenti  SELECT * FROM $SYSTEM.DISCOVER_STORAGE_TABLE_COLUMN_SEGMENT #sqlsatParma #sqlsat355 November 22nd, 2014
  • 42. Quanto spazio uso per il mio modello?  In alternativa alle DMV usate il PowerPivot di Kasper De Jonge.  Si apre un foglio excel in cui da powerpivot interrogo le DMV su un istanza di analisys services http://www.powerpivotblog.nl/what-is-using-all-that-memory-on- my-analysis-server-instance/ #sqlsatParma #sqlsat355 November 22nd, 2014
  • 43. Best Practice (ridurre il dictionary)  Ridurre la lunghezza delle stringhe  Ridurre il numero di valori distinti  Dividere DateTime in due colonne (troppi valori distinti)  Date  Time  Deve essere fissata una precisione per i valori floating point  76.201 diventa 76.2  Cercate di risolvere tutto a livello di sorgente dati e non in colonne calcolate (esempio con le viste) #sqlsatParma #sqlsat355 November 22nd, 2014
  • 44. Best Practice (ridurre dimensioni tabelle)  Attenzione alle Junk Dimensions. Faccio la cross join della distinct di questi valori junk e li metto nella tabella junk e poi ci punto dentro con un intero  Meglio + campi con pochi valori distinti sulla tabella dei fatti che uno che è il cross join dei valori distinti  Se poi ho dimensioni con solo Id e descrizione è meglio memorizzare la descrizione nei fatti  Descrizione occupa come l’Id nei fatti  Non pago un join a query time  Ho un tabella in meno da memorizzare che è inutile #sqlsatParma #sqlsat355 November 22nd, 2014
  • 45. Best Practice (ridurre dimensioni tabelle)  Evitare risultati parziali in colonne calcolate  essi tendono ad avere molti valori distinti  aumentano il numero di colonne  Rimuovere le colonne non utilizzate #sqlsatParma #sqlsat355 November 22nd, 2014
  • 46. Best Practice dimensioni degeneri  Problema -> Memorizzare un ID per il DrillThrought nei report è costoso (sacco di valori distinti)  Un solo valore per ogni riga  un grande dizionario per grandi tabelle  Soluzione -> Splittare in più colonne  Tabella di 100 milioni di righe. N° di fattura che è dato da anno + progressivo. Lo divido in due o più colonne. Le colonne hanno un dizionario più piccolo.  Se poi lo devo visualizzare sul report rimaterializzare lo faccio su un sottoinsieme di righe . #sqlsatParma #sqlsat355 November 22nd, 2014
  • 47. Workbook Optimizer  esamina la composizione del modello di dati all'interno della vostra cartella di lavoro di PowerPivot http://www.microsoft.com/en-us/download/details.aspx?id=38793  vede se i dati in essa contenuti possono occupare meno spazio  vede se possibile fare una migliore compressione  Non è il massimo deve migliorare molto #sqlsatParma #sqlsat355 November 22nd, 2014
  • 48. Conclusioni su xVelocity  Ha degli algoritmi di compressione molto efficienti  Molto veloce sulle colonne singole  L’accesso a più colonne richiede la materializzazione  Metodo di memorizzazione diverso dai classici database  Richiede un cambiamento di mentalità  Tentate di pensare a colonne singole  Tutte queste caratteristiche si riflettono in DAX. #sqlsatParma #sqlsat355 November 22nd, 2014
  • 49. DEMO  Testiamo tutto quello fino a qui imparato su un caso reale di foglio excel bello grande. #sqlsatParma #sqlsat355 November 22nd, 2014
  • 50. THANKS! #sqlsatParma #sqlsat355 #sqlsatParma #sqlsat355 November 22nd, 2014