50
February 28, 2015 February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: [email protected] site: www.marcopozzan.it

February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: [email protected] site:

Embed Size (px)

Citation preview

Page 1: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

xVelocity in Deep

Marco Pozzan

twitter: @marcopozzan

email: [email protected]

site: www.marcopozzan.it

Page 2: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

#sqlsatPordenone#sqlsat367February 28, 2015

Sponsors

Page 3: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Organizers

Page 4: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Speaker info

MVP SQL Server Presidente della community 1nn0va (

www.innovazionefvg.net) Business Intelligence consultant per

Beantech (www.beantech.it) Docente ITS all’Università di Pordenone Partecipo agli eventi community

Page 5: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 6: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 7: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Gestione delle query

PROCESS = Lettura dalla sorgente dati Vertipaq contiene il risultato del processing del

database

DAX/MDX query

Analysis Services

2012 Tabular Model

In-Memory Mode (Motore di query)

DirectQuery Mode (Motore di

query)

Vertipaq Storage

External Data

SourcesSQL Query

Query

Query

Storage engine query

Process

Storage engine query

Storage engine query

Page 8: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Che cosa è xVelocity in-memory?

E’ un database in memoria (dati sono in memoria) E’ basato su una metodologia relazionale Database colonnare

Page 9: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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 12 Geoffrey Gonzalez 06/02/1977 00:00 S 23 Blake Collins 23/04/1975 00:00 M 04 Alexa Watson 25/08/1977 00:00 S 05 Jacquelyn Dominguez 27/09/1977 00:00 M 16 Casey Gutierrez 17/12/1977 00:00 M 17 Colleen Lu 17/07/1973 00:00 M 28 Jeremiah Stewart 26/06/1979 00:00 S 19 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 12 Geoffrey Gonzalez 06/02/1977 00:00 S 23 Blake Collins 23/04/1975 00:00 M 04 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 16 Casey Gutierrez 17/12/1977 00:00 M 17 Colleen Lu 17/07/1973 00:00 M 28 Jeremiah Stewart 26/06/1979 00:00 S 19 Leah Li 06/10/1976 00:00 S 0

Page 10: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 11: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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)

Page 12: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 13: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Caratteristiche di un column storage

Portiamo il concetto di indice in memoria Estremizziamo il concetto di indice

Id FirstName LastName BirthDate Marital Status Children

1 Larry Gill 13/04/1977 00:00 M 12 Geoffrey Gonzalez 06/02/1977 00:00 S 23 Blake Collins 23/04/1975 00:00 M 04 Alexa Watson 25/08/1977 00:00 S 05 Jacquelyn Dominguez 27/09/1977 00:00 M 16 Casey Gutierrez 17/12/1977 00:00 M 17 Colleen Lu 17/07/1973 00:00 M 28 Jeremiah Stewart 26/06/1979 00:00 S 19 Leah Li 06/10/1976 00:00 S 0

Id

123456789

FirstName

LarryGeoffrey

BlakeAlexa

JacquelynCasey

ColleenJeremiah

Leah

LastName

GillGonzalez

CollinsWatson

DominguezGutierrez

LuStewart

Li

BirthDate

13/04/1977 00:0006/02/1977 00:0023/04/1975 00:0025/08/1977 00:0027/09/1977 00:0017/12/1977 00:0017/07/1973 00:0026/06/1979 00:0006/10/1976 00:00

Marital Status

MSMSMMMSS

Children

120011210

Un file per colonna

Page 14: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 15: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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 *

Page 16: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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 )

Page 17: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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)

Page 18: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 19: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Run Length Encoding (RLE) - 1 livello

Potrei anche decidere di togliere la colonna inizio e tenere solo la fine

Children

11111...22222222

....

Children Inizio Lunghezza

1 1 200

2 201 400

FirstName

LarryLarryLarry

...GeoffreyGeoffreyGeoffrey

...AlexaAlexaAlexa

...ColleenColleen

...

FirstName Lunghezza

Larry 400

Geoffrey 400

Alexa 100

Colleen 100

BirthDate13/04/197713/05/197713/06/1977

....15/04/198016/04/194713/04/1976

...13/04/197613/04/197613/04/1976

...13/04/199013/04/1934

...

BirthDate lunghezza13/04/1977 113/05/1977 113/06/1977 1

....15/04/1980 116/04/1947 113/04/1976 1

...13/04/1976 113/04/1976 113/04/1976 1

...13/04/1990 113/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.

Page 20: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 21: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Dictionary encoding - 2 livello

Più importante di RLE Vediamo i passi per creare il Dictionary

1. Vertipaq legge una colonna di tipo stringa2. Effettua il distinct della colonna3. Ogni valore stringa è associato ad un numero in un

Dictionary4. Sostituisco i valori stringa nella colonna con i numeri

del Dictionary

Page 22: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

QuarterQ1Q4Q1...Q2Q3Q1...Q3Q3Q2...Q1Q1....

DISTINCT

Indice Quarter

1 Q1

2 Q2

3 Q3

4 Q4

Quarter

111...222...333...44

....

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

Ve

rsion

e co

mp

ressa

Dizio

na

rio

Page 23: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 24: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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 datatype 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

Page 25: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 26: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 27: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 28: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 29: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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)

Page 30: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Segmentation

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

Fasi della segmentazione durante il processing

Page 31: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 32: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Configurazione della segmentazione La configurazione e a livello di istanza DefaultSegmentRowCount (0 = default) ProcessingTimeboxSecPerMRow per decidere il tempo entro al

quale deve ordinare

Page 33: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Uso memoria durante il processing Process data: carica, compressione, memorizzazione Process recalc: colonna calcolate, indici, relazioni, gerarchie Process Full: data + recalc Process transazionale

Il vecchio cubo è tenuto in memoria e continua a rispondere Nuovi dai sono processati e alla fine si scambiano i cubi

In totale un oggetto necessita di tre volte del suo spazio Memoria per tutti i dati 1x e memoria per il processing 2x

Evitare di fare il process full o il process su singola tabella Eseguire il ProcessClear => attenzione a fare il backup

Page 34: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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.

Page 35: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 36: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Materialization

Se vogliamo eseguire su un database colonnare la seguente query:

Ci sono diverse tecniche ma agli estremi ci sono: Early Materialization Late Materializzation

SELECT SUM(num730) AS N730,[COD_Ufficio]FROM [dbo].[Dichiarazioni730]WHERE [COD_Utente] = 345 AND [Tipo730] = 1GROUP BY [COD_Ufficio]

Tipo730

1

2

1

1

Cod_Ufficio

4555

2345

6545

444

num730

234

100

400

3

COD_Utente

345

1678

345

100

Page 37: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

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

SELECT SUM(num730) AS N730,[COD_Ufficio]FROM [dbo].[Dichiarazioni730]WHERE [COD_Utente] = 345 AND [Tipo730] = 1GROUP BY [COD_Ufficio]

Page 38: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Late materialization

Tipo730

1

2

1

1

Cod_Ufficio

4555

2345

4555

444

num730

234

100

400

3

COD_Utente

345

1678

345

100

Bitmap

1

0

1

0

Applico la clausola where sulle due colonne separate

Materializzo

4555 234

4555 400

Sommo

4555 634

SELECT SUM(num730) AS N730,[COD_Ufficio]FROM [dbo].[Dichiarazioni730]WHERE [COD_Utente] = 345 AND [Tipo730] = 1GROUP BY [COD_Ufficio]

COD_Utente

345

1678

345

100

Tipo730

1

2

1

1

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

Applico la bitmap

Cod_Ufficio

4555

4555

num730

234

400

Page 39: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 40: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Quanto spazio uso per il mio modello?

Nella directory dei dati, c’è un folder per ogni database ..\Microsoft SQL Server\MSAS11.MSSQLSERVER\OLAP\Data 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

Page 41: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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_SEGMENTS

Page 42: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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/

Page 43: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Best Practice (ridurre i 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)

Page 44: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Best Practice (ridurre dimensione tabelle) Evitare risultati parziali in colonne calcolate

essi tendono ad avere molti valori distinti aumentano il numero di colonne

Rimuovere le colonne non utilizzate

Page 45: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Best Practice per le junk dimensions 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

Page 46: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

Best Practice per le 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 .

Page 47: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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

Page 48: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

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.

Page 49: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

DEMO

Testiamo tutto quello fino a qui imparato su un caso reale di foglio excel bello grande.

Page 50: February 28, 2015 #sqlsatPordenone #sqlsat367 xVelocity in Deep Marco Pozzan twitter: @marcopozzan email: info@marcopozzan.it site:

February 28, 2015February 28, 2015 #sqlsatPordenone#sqlsat367

THANKS!

#sqlsatPordenone#sqlsat367

Feedback form: http://speakerscore.com/8N8C