La risoluzione dei problemi delle prestazioni è un'arte e una scienza. L'arte viene dall'esperienza (e dall'apprendimento dalle esperienze degli altri) e la scienza viene da linee guida ben note su cosa fare in quali scenari.
O almeno questo è ciò che mi piace pensare e insegnare.
In realtà, molti DBA e sviluppatori là fuori praticano ciò che chiamo "risoluzione dei problemi delle prestazioni a scatti". Ciò accade comunemente quando un problema di prestazioni ha raggiunto la fase critica con, ad esempio, il timeout delle query, i processi che funzionano lentamente o non riescono, gli utenti scontenti e la direzione che desidera risposte e un'azione rapida!
L'"improvvisazione" deriva dal fare un'analisi superficiale del problema e saltare alla conclusione (in realtà è aggrapparsi a una cannuccia) che il sintomo più prevalente deve essere la causa principale e cercare di affrontarlo, inutilmente o con scarso successo, spesso utilizzando consigli fuorvianti o addirittura errati trovati online. Ciò porta a molta frustrazione e spreco di tempo e spesso porta a sprechi di denaro quando l'organizzazione decide di provare a risolvere il problema con l'hardware aggiornando il server e/o il sottosistema di I/O, solo per scoprire che il problema è ancora presente o riappare di nuovo abbastanza rapidamente.
L'analisi delle statistiche di attesa è una delle aree in cui è più facile improvvisare, e in questo post parlerò di alcuni dei tipi di attesa comuni e degli errori che le persone fanno intorno a loro. Non c'è spazio in un articolo come questo per approfondire cosa fare in ciascun caso, ma ti fornirò informazioni sufficienti per indirizzarti nella giusta direzione.
LCK_M_XX
La maggior parte delle persone presume che se le attese di blocco sono le più diffuse, il problema deve essere una sorta di problema di blocco. Spesso lo è, ad esempio la mancanza di un indice non cluster adatto che causa un'analisi della tabella nei livelli di isolamento REPEATABLE_READ o SERIALIZABLE che si trasforma in un blocco della tabella S. (E come suggerimento rapido, se pensi di non utilizzare mai SERIALIZABLE, lo fai se utilizzi transazioni distribuite:tutto viene convertito in SERIALIZABLE sotto le coperte, il che può portare a blocchi e deadlock imprevisti.)
Tuttavia, capita spesso che il blocco sia causato da qualcos'altro. Sotto il livello di isolamento READ_COMMITTED predefinito, i blocchi che coprono le modifiche vengono mantenuti fino al commit della transazione e bloccheranno le letture e altri aggiornamenti nelle stesse righe. Se qualcosa impedisce il commit di una transazione, ciò potrebbe causare la visualizzazione del blocco.
Ad esempio, se il database è sottoposto a mirroring sincrono, la transazione non può eseguire il commit e rilasciare i suoi blocchi fino a quando i record di registro non sono stati inviati al mirror e scritti nell'unità di registro del mirror. Se la rete è gravemente congestionata o si verifica un'enorme contesa di I/O sul mirror, ciò potrebbe ritardare gravemente l'operazione di mirroring e quindi richiedere molto più tempo per il commit della transazione. Sembrerebbe un blocco, ma la causa principale è la contesa di risorse a che fare con il mirroring.
Per le attese di blocco, a meno che la causa non sia ovvia osservando il piano di query, bloccare la risorsa (ad es. livello di tabella che indica l'escalation del blocco o il livello di isolamento, seguire la catena di blocco (utilizzando uno script che percorre la colonna blocking_session_id in sys.dm_exec_requests e quindi guarda cosa sta aspettando il thread all'inizio della catena di blocco. Questo indicherà la causa principale.
ASYNC_NETWORK_IO
Il nome di questo crea molta confusione. Su quale parola ti concentri? RETE. La causa di questo tipo di attesa di solito non ha nulla a che fare con la rete. In realtà dovrebbe essere chiamato WAITING_FOR_APP_ACK (riconoscimento) o qualcosa di simile, poiché è esattamente ciò che sta accadendo:SQL Server ha inviato alcuni dati a un client e sta aspettando che il client riconosca di aver consumato i dati.
Una delle mie demo preferite da fare quando insegno le statistiche di attesa è eseguire una query che restituisce un set di risultati di grandi dimensioni in Management Studio e guardare il server accumulare attese ASYNC_NETWORK_IO. Chiaramente non è coinvolta alcuna rete:è solo SSMS che impiega molto tempo per rispondere a SQL Server. Sta facendo ciò che è noto come RBAR (Row-By-Agonizing-Row), in cui solo una riga alla volta viene estratta dai risultati ed elaborata, invece di memorizzare nella cache tutti i risultati e quindi rispondere immediatamente a SQL Server e procedere con l'elaborazione righe memorizzate nella cache.
Questa è la causa principale delle attese di ASYNC_NETWORK_IO:una progettazione scadente dell'applicazione. Quindi esaminerei se il server che esegue il codice dell'applicazione presenta un problema di prestazioni, anche se il codice dell'applicazione stesso è ben progettato. Occasionalmente è la rete, ma nella mia esperienza è raro.
OLEDB
La reazione istintiva comune qui è di equiparare questo tipo di attesa ai server collegati. Tuttavia, questo tempo di attesa è diventato più comune vedere quando SQL Server 2005 è stato rilasciato, perché 2005 conteneva una serie di nuove DMV e le DMV utilizzano principalmente OLE DB sotto le coperte. Prima di cercare problemi con i server collegati, verificherei se uno strumento di monitoraggio esegue costantemente DMV sul server.
Se disponi di server collegati, continua la risoluzione dei problemi andando sul server collegato e osservando le statistiche di attesa per vedere qual è il problema più diffuso, quindi continua la stessa analisi.
Un'altra cosa che può causare attese OLEDB è DBCC CHECKDB (e comandi correlati). Utilizza un set di righe OLE DB per comunicare informazioni tra i sottosistemi Processore di query e Motore di archiviazione.
Altre attese
Alcune delle altre attese che causano reazioni istintive sono CXPACKET, PAGEIOLATCH_XX, SOS_SCHEDULER_YIELD e WRITELOG, e le tratterò nel mio post il mese prossimo.
Riepilogo
Quando hai un problema di prestazioni, prenditi il tempo necessario per comprendere i dati che stai esaminando ed eseguire ulteriori indagini per restringere il campo alla causa principale del problema. Non limitarti a cogliere quella che sembra essere la statistica di attesa più alta e segui il primo consiglio che trovi online (a meno che non provenga da una fonte nota e affidabile) o probabilmente non risolverai il tuo problema, e potresti anche peggiora le cose.
Per quanto riguarda le statistiche generali sull'attesa, puoi trovare ulteriori informazioni sull'utilizzo per la risoluzione dei problemi relativi alle prestazioni in:
- La mia serie di post sul blog, a partire dalle statistiche di attesa, o per favore dimmi dove fa male
- La mia libreria Tipi di attesa e classi Latch qui
- Il mio corso di formazione online Pluralsight SQL Server:risoluzione dei problemi delle prestazioni utilizzando le statistiche di attesa
- Consigliere prestazioni SQL Sentry
Questo è stato il primo di una serie di post che farò nel corso di quest'anno in cui si parla di (re)azioni istintive su SQL Server e perché sono la cosa sbagliata da fare. Alla prossima volta, buona risoluzione dei problemi!