SQL Server 2019 ed il Batch Mode on Rowstore

Ciao a tutti!

Ben ritrovati.
Siete pronti per continuare la carrellata delle novità introdotte da SQL Server 2019?
Già perchè se avete letto i precendenti articoli ormai saprete che sono tante.

Noi, come al solito, ci focalizzeremo sulla novità che ci consentono di migliorare le prestazioni ed quindi anche la novità vedremo ci consentità di ottenere prestazioni maggiori!

Parliamo di Batch Mode on RowStore.

Prima però occorre fare un passo indietro per vedere che cos'è un Batch!

Già cos'è un Batch?


Detto in modo semplice un batch è una struttura ampia 64 KB che al suo interno contiene un gruppo di righe che vanno a 64 a 900 a seconda del numero di colonne di cui sono composte.
Internamente la sua struttura è fatta così: i dati sono contenuti un Column Vector uno per ogni colonna e poi prefense anche n qualifyng row vector dentro al quale viene memorizzato per ogni riga che questa fa ancora parte del batch oppure se è stata cancellata.

Quali sono i vantaggi dati dall'utilizzare i batch?

beh i vantaggi sono parecchi.
SQL Server infatti valuta i metadati una sola volta per tutto il batch anzichè farlo per ogni riga.
Così facendo viene ridotto l'uso della CPU ed inolte la Cache del processore viene sfruttata in modo migliore.
Questa tecnica è in grado di migliorare le prestazioni della nostra query fino a 10 volte.


Facciamo ora un po di storia prima di tornare a noi ed al nostro SQL Server 2019.

Diciamo che i batch sono stati introdotti già da SQL Server 2012.
Erano però stati aggiunti per supportare le tabelle e le interrogazioni in cui erano presenti degli indici columnstore e per questo motivo la feature venne chiamata Batch Mode on ColumnStore.

Oggi con SQL Server 2019 la stessa feature viene resa disponibile anche per le tabelle in cui la elaborazione avviene per riga e viene quindi denominata Batch Mode on RowStore.

Tuttavia non in tutte le Query vedremo che verrà applicata per modalità
Ma bando alle ciance proviamo subito questa nuova feature!

Siete pronti? Si? Allora eseguite l' SMSS e seguitemi!

 

Batch Mode on Rowstore


Creiamo per prima cosa una tabella che chiamiamo movimenti.


Create Table movimenti 
(id int identity (1,1), 
Anno int, Quantita float, 
Prezzo float, 
Classificatore VarChar(10)
)


Riempiamoli con un numero elevato di righe eseguenti tanti insert come sotto:

Insert into movimenti (anno, quantita, prezzo, Classificatore) values (1980, 1,1.5, 'A')


Poi impostiamo il livello di compatibilità su 140 (SQL Server 2017) ed eseguiamo la seguente Query:
       
SELECT Classificatore,
       SUM(Quantita),
       SUM(Prezzo)
FROM movimenti
GROUP BY Classificatore
ORDER BY Classificatore

Ora analizziamone i risultati:

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'movimenti'. Scan count 9, logical reads 2540, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

(1 riga interessata)

Tempo di esecuzione SQL Server:
 tempo di CPU = 735 ms, tempo trascorso = 316 ms.



 Dal piano di esecuzione vediamo che tutti gli operatori sono in modalità Row.




Ora impostiamo il livello di compatibilità nativo di SQL Server 2019 ovvero il 150 e rifacciamo i nostri test!

(4 righe interessate)
Table 'movimenti'. Scan count 1, logical reads 2540, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

(1 riga interessata)

Tempo di esecuzione SQL Server:
 tempo di CPU = 156 ms, tempo trascorso = 242 ms.
Tempo di analisi e compilazione SQL Server:
   tempo di CPU = 0 ms, tempo trascorso = 0 ms.



Cosa osservate? La duratà della nostra Query si è ridotta di un terzo!

SQL Server Execution plan property




Il piano di esecuzione si è modificato e viene adottata la modalità Batch!

Non entriamo oggi in dettagli maggiori per cui anche per oggi è tutto.


Spero l'articolo vi sia piaciuto!
Un saluto

Luca Biondi @ SQLServerPerformance blog!


 






Next post: SQL Server 2019 e la funzione Approx_Count_Distinct

Previous post: SQL Server 2019 e le inline scalar function

Comments

I Post più popolari

SQL Server, execution plan and the lazy spool (clearly explained)

SQL Server, datetime vs. datetime2

La clausola NOLOCK. Approfondiamo e facciamo chiarezza!