Quali sono i motivi della mancanza di un piano dalla cache per le procedure memorizzate?
WITH RECOMPILE
- SQL dinamico
- Codice criptato
- Modifiche significative dei dati
- Aggiorna statistiche
- Cos'altro?
Di recente ho lavorato su 2 server (SQL Server 2008 R2 e SQL Server 2012) che non avevano piani nella cache per procedure memorizzate ad alta intensità di risorse. Molte, forse tutte, le dichiarazioni all'interno delle procedure memorizzate non avevano piani nella cache. Alcune delle procedure memorizzate vengono eseguite abbastanza frequentemente come alcune volte al secondo.
Nessuna pressione di memoria di sorta. Uno dei server ha molto più hardware del necessario.
Pensavo che i piani mancanti fossero dovuti a creazioni temporanee di tabelle nel mezzo delle procedure memorizzate, ma quelle sembrano essere vecchie informazioni di SQL Server 2000 o precedenti. A partire da SQL Server 2005, i ricompilamenti si verificano a livello di istruzione per le istruzioni dopo DDL. È vero in tutti i casi o può ancora succedere nelle versioni più recenti?
Cos'altro potrebbe essere il colpevole dei piani mancanti? Ho sfogliato alcuni articoli su questo argomento, ma nulla sembra adattarsi.
L'ottimizzazione per i carichi di lavoro ad hoc è abilitata sul server che sto esaminando questa settimana. Una delle procedure memorizzate viene eseguita solo una volta al giorno. Ho il codice per quello. Non ho il codice per quello che viene eseguito più di 100 volte al minuto, ma posso ottenerlo. Non sarò in grado di pubblicare il codice, ma posso descriverlo in relazione alla mia domanda.
Non credo che nessuno stia liberando la cache delle procedure o rilasciando buffer puliti. Questo client utilizza DPA Solarwinds come uno dei loro strumenti di monitoraggio. DPA ha catturato uno dei piani di esecuzione per la dichiarazione nel proc memorizzato che viene chiamato una volta al giorno. Tale affermazione ha una grande quantità di letture a causa della WHERE
clausola non sargable . Se DPA ha acquisito l'istruzione, allora è un piano stimato e si trovava contemporaneamente nella cache del piano. Semplicemente non c'è quando stiamo risolvendo i problemi. Li farò iniziare a registrare sp_WhoIsActive
su un tavolo.
Sto usando sp_BlitzCache
. (Lavoro per Brent Ozar Unlimited) Questo mostrerà il piano per l'intera procedura memorizzata, nonché i piani per le singole dichiarazioni, se esistenti. Se non esistono, ha questo per un avvertimento "Non siamo riusciti a trovare un piano per questa query. Possibili ragioni per questo includono SQL dinamico, RECOMPILE
suggerimenti e codice crittografato". E quell'avvertimento è anche sulle dichiarazioni.
TF 2371 non è a posto. Sto guardando le statistiche di attesa. Il server è piuttosto annoiato. PLE è oltre 130.000.
Ora ho il codice per altre 2 procedure memorizzate. Uno di questi utilizza SQL dinamico con in exec (@sql)
modo che uno sappia perché non esiste un piano per esso. Ma l'altro, e questo è quello che corre più di 100 volte al minuto, non ha nulla di straordinario. L'unica cosa che si distingue in questo è che le tabelle temporanee vengono create nel mezzo di oltre 1000 righe di codice. Richiama anche un mucchio di stored procedure figlio.
Per quanto riguarda la memorizzazione nella cache dei piani in SQL Server 2008 , non vedo valori letterali> = 8k, ma una delle procedure memorizzate ha un commento su un inserimento in blocco prima di chiamare un'altra procedura memorizzata. Ma l'inserto di massa non viene visualizzato nella stored procedure esterna che sto esaminando. La sezione "Soglia di ricompilazione" dell'articolo è interessante. Quello che vedo per le tabelle temporanee sono tonnellate di INSERT (che potrebbero risultare in milioni di righe), alcuni aggiornamenti ed eliminazioni. Quindi molte modifiche ai dati delle tabelle temporanee. Milioni.