Comprensione di statistiche, piani di esecuzione e "problema chiave crescente"


11

Sto cercando di comprendere meglio (concettualmente) la relazione tra statistiche, piani di esecuzione, esecuzione di procedure memorizzate.

Sono corretto nel dire che le statistiche vengono utilizzate solo durante la creazione del piano di esecuzione per una procedura memorizzata e non vengono utilizzate nel contesto di esecuzione effettivo? In altre parole, se questo è vero, una volta creato il piano (e supponendo che sia riutilizzato correttamente), quanto sono importanti le statistiche "aggiornate"?

Sono stato particolarmente motivato da un articolo che ho letto ( Statistiche, stime delle righe e colonna della data crescente ) che descrive uno scenario molto simile a quello che incontro quotidianamente con diversi database dei nostri clienti.

Abbiamo una colonna data / ora crescente in una delle nostre tabelle più grandi che interroghiamo regolarmente utilizzando una specifica procedura memorizzata.

Come evitare che i piani di esecuzione diventino obsoleti quando si aggiungono centomila righe al giorno?

Se aggiorniamo frequentemente le statistiche per combattere questo problema, avrebbe senso utilizzare il suggerimento OPTION (RECOMPILE) sulla query di questa procedura memorizzata?

Qualsiasi consiglio o raccomandazione sarebbe apprezzato.

Aggiornamento : sto usando SQL Server 2012 (SP1).

Risposte:


5

Sono corretto nel dire che le statistiche vengono utilizzate solo durante la creazione del piano di esecuzione per una procedura memorizzata e non vengono utilizzate nel contesto di esecuzione effettivo?

No, ciò che accade è che il piano di esecuzione per una stored procedure è memorizzato nella cache. Supponendo che la memoria disponibile sia sufficiente per continuare a conservare il piano, non cambierà a meno che non si verifichi una delle seguenti condizioni (dalla cache e dal riutilizzo del piano di esecuzione nella documentazione di SQL Server, enfasi aggiunta):

  • Modifiche apportate a una tabella o vista a cui fa riferimento la query (ALTER TABLE e ALTER VIEW).
  • Modifiche apportate a una singola procedura, che eliminerebbe tutti i piani per quella procedura dalla cache (ALTER PROCEDURE).
  • Modifiche a tutti gli indici utilizzati dal piano di esecuzione.
  • Aggiornamenti sulle statistiche utilizzate dal piano di esecuzione, generati in modo esplicito da un'istruzione, come UPDATE STATISTICS, o generati automaticamente.
  • Eliminazione di un indice utilizzato dal piano di esecuzione.
  • Una chiamata esplicita a sp_recompile.
  • Numerose modifiche alle chiavi (generate da istruzioni INSERT o DELETE di altri utenti che modificano una tabella a cui fa riferimento la query).
  • Per le tabelle con trigger, se il numero di righe nelle tabelle inserite o eliminate aumenta in modo significativo.
  • Esecuzione di una procedura memorizzata utilizzando l'opzione WITH RECOMPILE.

Pertanto, se le statistiche vengono aggiornate, il piano memorizzato nella cache terrà automaticamente conto delle nuove statistiche e verrà ricompilato.

Come evitare che i piani di esecuzione diventino obsoleti quando si aggiungono centomila righe al giorno?

Un modo è se ci sono molti aggiornamenti alla tabella, come menzionato sopra. Alcune centinaia di migliaia di righe modificate possono soddisfare questa condizione. Ma se vuoi essere sicuro o avere un controllo più granulare: aggiornando le tue statistiche. È possibile consentire a SQL Server di creare e gestire automaticamente le statistiche o manualmente. Ulteriori informazioni su entrambi i metodi sono disponibili in Opzioni di aggiornamento automatico e Creazione automatica statistiche di SQL Server . Quando / se esegui una ricostruzione settimanale degli indici, ciò attiverà anche l'aggiornamento dei piani. Esegui alcuni test per vedere quale è il più vantaggioso per te, poiché l'aggiornamento delle statistiche troppo spesso potrebbe non produrre risultati di prestazioni reali.

Se aggiorniamo frequentemente le statistiche per combattere questo problema, avrebbe senso utilizzare il suggerimento OPTION (RECOMPILE) sulla query di questa procedura memorizzata?

Non è necessario utilizzarlo RECOMPILE, poiché in base all'estratto di cui sopra è possibile vedere che il piano di esecuzione viene aggiornato in modo appropriato ogni volta che sono disponibili nuove statistiche. Potresti stare bene con un aggiornamento delle statistiche di fine giornata (se sei veramente preoccupato) ma non penso che sia esplicitamente un'esigenza basata su ciò che hai detto finora. Ancora una volta, però, lo testerei per vedere quale impatto potrebbe avere sulle prestazioni della procedura memorizzata e pianificare di conseguenza.


RECOMPILEnon provocherebbe comunque un aggiornamento delle statistiche.
Martin Smith,

@MartinSmith Correct! Modificherò per renderlo più chiaro.
LowlyDBA

@LowlyDBA potresti riferirti al seguente argomento? dba.stackexchange.com/questions/207475/…
lukaszwinski

6

Ho ragione nel dire che le statistiche vengono utilizzate solo durante la creazione del piano di esecuzione

No, le statistiche obsolete possono causare una ricompilazione relativa all'ottimalità della dichiarazione interessata.

Abbiamo una colonna di data / ora crescente in una delle nostre tabelle più grandi che interroghiamo regolarmente

I piani di esecuzione subottimale causati dal fatto che i valori del predicato si trovano all'esterno (in particolare sopra) l'intervallo di valori memorizzati nell'istogramma statistico corrispondente è noto come Problema chiave crescente . La ricostruzione delle statistiche è una possibile soluzione, ma può richiedere molte risorse. Le alternative includono:

  • Traccia flag 2389 e 2390 . Ciò richiede che esista un indice con la colonna problematica come chiave principale. Non funziona con le tabelle partizionate ed è efficace solo in SQL Server 2014 se viene utilizzato lo stimatore cardinalità originale. Il flag di traccia 4139 può anche essere richiesto se l'oggetto statistico è marchiato stazionario.

  • Esegui l'upgrade a SQL Server 2014. Il nuovo stimatore della cardinalità include la logica per stimare oltre l'istogramma utilizzando le informazioni sulla densità media. Ciò può essere meno accurato rispetto ai flag di traccia 2389/2390 in alcune circostanze importanti.

  • Abilita aggiornamenti statistici automatici più frequenti per tabelle di grandi dimensioni con flag di traccia 2371 . Con questo flag di traccia, invece di aggiornare dopo il 20% + 500 modifiche, sono necessarie solo le SQRT(1000 * Table rows)modifiche . Questa non è una soluzione completa come quelle menzionate in precedenza, poiché gli aggiornamenti potrebbero non essere attivati ​​abbastanza spesso.

Se la fonte del tuo problema non è la compilazione di piani così frequente basata su valori predicati oltre l'istogramma, ma più sugli effetti della memorizzazione occasionale di un piano così scadente come risultato dello sniffing dei parametri, potresti anche considerare:

  • Disabilitazione dello sniffing dei parametri mediante il flag di traccia 4136
  • Utilizzo OPTIMIZE FOR (@parameter = value)per compilare un piano per un valore rappresentativo noto
  • Utilizzo OPTIMIZE FOR (@parameter UNKNOWN)per ottimizzare utilizzando la distribuzione media
  • Utilizzo OPTIMIZE FOR UNKNOWN(uguale a 4136, ma per query)
  • Usando OPTION (RECOMPILE)per compilare ogni volta, annusando il valore particolare. Se la stragrande maggioranza dei valori di runtime si trovano all'interno dell'istogramma, questo potrebbe essere efficace.

Per ulteriori informazioni sullo sniffing, l'incorporamento dei parametri e le opzioni di ricompilazione, vedere il mio articolo su SQLperformance.com.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.