Microsoft ha migliorato il contenuto dell'output ShowplanXML per SQL Server negli ultimi rilasci e in SQL Server 2017 CU3 ha introdotto le statistiche di esecuzione delle funzioni definite dall'utente (UDF) nel nodo QueryTimeStats dell'output XML. Questo è stato anche riportato in SQL Server 2016 nel Service Pack 2 per i piani di esecuzione effettivi. Questa funzionalità consente di conoscere in modo definitivo l'impatto dell'esecuzione di UDF scalare come parte delle caratteristiche prestazionali di una query. Tuttavia, c'è un problema interessante associato all'utilizzo di questa funzione; è necessario raccogliere il piano di esecuzione effettivo utilizzando una versione aggiornata di SQL Server Management Studio o utilizzando SentryOne Plan Explorer, altrimenti le informazioni verranno rimosse dal piano di esecuzione.
Confronto dei piani in diverse versioni di SSMS
Di recente ho presentato una sessione di gruppi di utenti a Chicago sull'ottimizzazione delle prestazioni delle query utilizzando la cache dei piani e durante la sessione stavo utilizzando l'ultima versione di SQL Server Management Studio in quel momento, la versione 17.5. All'epoca avevo anche aggiornato di recente la mia macchina virtuale a SQL Server 2016 Service Pack 2, quindi ho dimostrato le nuove informazioni su UdfElapsedTime e UdfCpuTime nello showplan effettivo QueryTimeStats e ho preso nota di scrivere un articolo su di esse. Quando sono tornato per iniziare effettivamente questo articolo, utilizzando la stessa identica query sulla stessa VM, non sono stato in grado di generare un piano di esecuzione effettivo che contenesse le informazioni UdfElapsedTime o UdfCpuTime nonostante i ripetuti tentativi. Non riuscivo a capire cosa stavo facendo di sbagliato e si è scoperto che la radice del problema era che avevo avviato accidentalmente SQL Server Management Studio 2016 invece di SQL Server Management Studio 17.5. Quando ho eseguito la stessa query in SSMS 17.5, ho improvvisamente recuperato le informazioni su UdfElapsedTime e UdfCpuTime. Vedi sotto per esempi dell'XML restituito da entrambe le versioni SSMS:
Showplan XML da SSMS 17.5
Showplan XML da SSMS 2016 – WaitStats e QueryTimeStats sono stati completamente rimossi
Ho utilizzato Microsoft Message Analyzer per produrre una traccia TCP del traffico di rete sulla porta 1433 tra un client che esegue SSMS 2016 e un'istanza di SQL Server 2016 SP2 per acquisire i pacchetti TDS inviati dal server al client. Ciò rivela che ShowPlanXML restituito dal server includeva le informazioni QueryTimeStats anche se non viene visualizzato in ShowPlanXML in SSMS 2016, quindi il client sta effettivamente eliminando tutti i campi non inclusi nella definizione dello schema fornita con il client.
Offset messaggio:1635
<.Q.u.e.r.y.T.i.m.e.S.t.a.t.s. .E.l.a.p.s.e.d.T.i.m.e.=.".2.6.7.". .C.p.u.T.i.m.e.=.".2.6.7.". .U.d.f.E.l.a.p.s.e.d.T.i.m.e.=.".2.1.5.". .U.d.f.C.p.u.T.i.m.e.=.".2.1.5.".>.<./.Q.u.e.r.y.T.i.m.e.S.t.a.t.s.>
Questo è qualcosa a cui prestare attenzione con i file .sqlplan generati utilizzando versioni client precedenti di SSMS e/o piani di esecuzione che vengono salvati o copiati da una versione precedente di SSMS, cosa che accade spesso quando lavoro con i client tramite e-mail.
In SSMS, l'analisi del piano di esecuzione grafico non fornisce alcuna indicazione dell'impatto sulle prestazioni dell'esecuzione della funzione scalare definita dall'utente nella query:
Se abbiamo basato la nostra analisi delle prestazioni rigorosamente sui costi di ciascun operatore, il calcolo scalare per l'esecuzione della funzione non sembra avere un impatto significativo sulle prestazioni. Inoltre, i suggerimenti per gli operatori non concretizzano le informazioni o contengono avvisi sull'impatto della funzione definita dall'utente. L'unico posto in cui vediamo attualmente le informazioni all'interno di SSMS è nell'XML del piano o nella finestra delle proprietà per l'operatore radice SELECT del piano, come mostrato di seguito:
Utilizzando le informazioni qui, tuttavia, possiamo vedere che UdfCpuTime è l'85,79% del CpuTime totale e UdfElapsedTime è il 64,44% del tempo trascorso totale per l'esecuzione della query (facendo i conti per calcolare le percentuali utilizzando QueryTimeStats CpuTime e UdfCpuTime (evidenziato in blu sopra) e ElapsedTime e UdfElapsedTime).
Utilizzo di SentryOne Plan Explorer per recuperare i piani
Uno dei miei strumenti gratuiti preferiti per aiutare con l'ottimizzazione delle prestazioni di SQL Server è SentryOne Plan Explorer e una delle funzionalità di Plan Explorer per molto tempo è stata la possibilità di generare un piano di esecuzione effettivo incollando il testo del comando in una nuova finestra e facendo clic sul pulsante Ottieni piano effettivo, come mostrato di seguito.
Poiché Plan Explorer legge ShowplanXML così come viene fornito dal motore di SQL Server, conterrà anche le informazioni avanzate in QueryTimeStats. Tuttavia, se si apre un piano di esecuzione salvato da una versione precedente di Management Studio o se si utilizza Plan Explorer Addin per SSMS in una versione precedente per visualizzare il piano in Plan Explorer, le informazioni avanzate non verranno visualizzate.
La griglia Istruzione della scheda Risultati in Plan Explorer può essere aggiornata utilizzando il Selettore colonne per aggiungere le colonne Durata UDF e CPU UDF insieme alle colonne esistenti nella griglia, rendendo facile vedere dove l'esecuzione della funzione definita dall'utente sta avendo un impatto per grandi lotti multi-rendiconto. Plan Explorer fornisce anche l'evidenziazione di queste colonne quando rappresentano una parte significativa della CPU complessiva e/o della durata, come mostrato di seguito.
Anche le informazioni sul diagramma del piano in Plan Explorer sono state migliorate. Ecco i diagrammi che utilizzano Costi per CPU + I/O e quindi Costi per CPU:
Diagramma del piano utilizzando i costi da CPU + I/O
Diagramma del piano utilizzando i costi dalla CPU
Sono presenti avvisi aggiuntivi sull'operatore SELECT root quando le statistiche di esecuzione per le funzioni definite dall'utente indicano che rappresentano una parte significativa della CPU complessiva e/o della durata complessiva:
Descrizione comando per la radice operatore SELEZIONA
L'operatore Calcola scalare ha anche un avviso in Plan Explorer basato sul conteggio delle righe elaborato dall'operazione, anche per i piani che non includono i miglioramenti per ShowplanXML:
Descrizione comando per il calcolo Operatore scalare
La visualizzazione dei costi per CPU può aiutare a identificare gli operatori con costi CPU nascosti che potrebbero essere sovrastati dall'I/O. Questa capacità di spostare leggermente la visualizzazione per risolvere i problemi della CPU o dell'I/O da sola è uno dei tanti fattori di differenziazione tra Plan Explorer e SSMS. Ecco il menu contestuale del diagramma in cui puoi cambiare questa vista:
Conclusione
I miglioramenti apportati all'XML Showplan in SQL Server rendono molto più semplice determinare l'impatto complessivo delle funzioni scalari definite dall'utente sulle prestazioni delle query in SQL Server 2016 Service Pack 2 e SQL Server 2017 Cumulative Update 3, purché si utilizzi un altro versione recente degli strumenti client o Plan Explorer per recuperare il piano di esecuzione.