Durante un'indagine su una query lenta è emerso che il piano di esecuzione era eccezionalmente non ottimale (un ciclo nidificato che eseguiva 9 milioni di esecuzioni di una ricerca in cui il numero stimato di esecuzioni era 1). Avendo confermato che alcune statistiche pertinenti erano davvero obsolete, ho ricostruito le statistiche e il problema delle prestazioni è stato effettivamente risolto.
Questo database ha le statistiche di aggiornamento automatico abilitate (attivata per impostazione predefinita). Comprendo che esiste una soglia per gli aggiornamenti delle statistiche automatiche in base al fatto che ci sono modifiche del 20% + 500 righe (aggiornamento / inserimento / eliminazione). Questa soglia sembra essere stata ampiamente superata su più indici, in quanto tale sembra che ci sia (A) un problema con gli aggiornamenti automatici o (B) C'è molto di più nella strategia di aggiornamento di quello che sono riuscito a trovare online documentazione.
Apprezzo che sia possibile impostare un'attività pianificata per aggiornare le statistiche e questo è probabilmente l'approccio che adottiamo se non è possibile trovare un'altra soluzione, ma ci lascia confusi sul perché un numero così elevato di modifiche non provocherebbe un aggiornamento automatico per alcune statistiche: capire perché potrebbe aiutarci a decidere quali statistiche devono essere aggiornate da un'attività pianificata.
Alcune note aggiuntive:
1) Il problema è stato riscontrato in un database in cui i dati vengono creati da un test di carico e come tale viene aggiunta una grande quantità di dati in un breve lasso di tempo, quindi se l'aggiornamento automatico si è verificato periodicamente (ad esempio una volta al giorno alle la maggior parte) quindi questo potrebbe spiegare alcuni dei comportamenti osservati. Inoltre i nostri test di carico tendono a stressare pesantemente il database, quindi mi chiedo se SQL stia rinviando gli aggiornamenti delle statistiche mentre c'è un carico pesante (e successivamente non aggiorna le statistiche per qualche motivo).
2) Nel tentativo di ricreare questo problema con uno script di test contenente successive istruzioni INSERT, SELECT e DELETE, il problema non si è verificato. Mi chiedo se la distinzione qui sia che queste istruzioni influenzano ciascuna più righe per ogni istruzione SQL, mentre il nostro script di test del carico tenderà a inserire le righe singolarmente.
3) Il DB in questione è impostato sul modello di recupero "Semplice".
Alcuni link rilevanti:
- Elenco di controllo per l'analisi delle query a esecuzione lenta
- Utilizzo delle statistiche per migliorare le prestazioni delle query
Ho anche sollevato questo problema tramite Microsoft Connect:
AGGIORNAMENTO 2011-06-30:
Su ulteriori indagini, credo che le statistiche non aggiornate oltre i livelli di soglia (ad es. 500 righe + 20%) siano statistiche che non vengono utilizzate dalla query del problema, quindi probabilmente verranno aggiornate quando viene eseguita una query quello li richiede. Per le statistiche che vengono utilizzate dalla query, questi vengono aggiornati regolarmente. Il problema rimanente è quindi che queste statistiche sono gravemente fuorvianti per l'ottimizzatore del piano di query dopo solo un numero relativamente basso di inserimenti (ad esempio, causando circa i 9 milioni di cui sopra, dove il numero stimato era 1).
Il mio sospetto in questo momento è che il problema sia legato a una cattiva scelta della chiave primaria, la chiave è un identificatore univoco creato usando NEWID (), e questo quindi crea un indice altamente frammentato molto rapidamente, specialmente come fattore di riempimento predefinito in SQL Il server è al 100%. La mia impressione è che ciò si traduca in qualche modo in statistiche fuorvianti dopo relativamente pochi inserimenti di righe, meno della soglia per il ricalcolo delle statistiche. Questo è probabilmente un problema dato che ho generato molti dati senza ricostruire gli indici a metà strada, quindi le statistiche scadenti possono essere una conseguenza della frammentazione degli indici risultante molto elevata. Penso di dover aggiungere cicli di manutenzione di SQL Server nel mio test di carico per avere un'idea migliore delle prestazioni su un sistema reale per lunghi periodi di tempo.
AGGIORNAMENTO 2012-01-10:
Un altro fattore da considerare. Due flag di traccia sono stati aggiunti a SQL Server 2005 (e sembrano essere ancora presenti nel 2008) per ovviare a carenze specifiche legate al verificarsi di statistiche obsolete e / o fuorvianti. Le bandiere in questione sono:
DBCC TRACEON(2389)
DBCC TRACEON(2390)
MSDN: WebLog di Ian Jose: chiavi ascendenti e statistiche di correzione rapida automatica su colonne ascendenti, Fabiano Amorim
Ovviamente dovresti stare molto attento quando decidi di abilitare questi flag perché potrebbero avere effetti dannosi.