Soliti sospetti:
- costanti in ad hoc, parametri nel codice
- mancata corrispondenza dei tipi di dati nel codice
- fiuto dei parametri
Punto 1: l'ottimizzatore può scegliere il piano migliore per le costanti.
Cambia le costanti = cambia il piano. Un plen parametrizzato è resuable
Il punto 2 introdurrà conversioni implicite a causa della precedenza del tipo di dati,
ad esempio la colonna varchar rispetto al parametro nvarchar
Punto 3: utilizzare il mascheramento dei parametri o OTTIMIZZA PER SCONOSCIUTO
Modifica: per testare: eseguire stored procedure, eseguire sp_updatestats, eseguire nuovamente. Ciò invaliderà i piani memorizzati nella cache, meglio quindi svuotare la cache dei piani
Modifica: dopo il commento di jcolebrand
È possibile disabilitare lo sniffing in diversi modi. I 3 principali sono
- RECOMPILE. Questo è sciocco IMO.
- OTTIMIZZARE (sic) PER SCONOSCIUTO
- Mascheramento dei parametri
Mascheramento dei parametri:
DECLARE @MaskedParam varchar(10)
SELECT @MaskedParam = @SignaureParam
SELECT...WHERE column = @MaskedParam
Il mascheramento e il suggerimento OPTIMIZE hanno lo stesso effetto (forse per motivi diversi). Cioè, l'ottimizzatore deve utilizzare le statistiche e la distribuzione dei dati ( Nota: ancora in fase di test da Mark Storey-Smith ) valutare i parametri in base ai propri meriti ? , piuttosto che quello che erano l'ultima chiamata. L'ottimizzatore può ricompilare o meno. SQL Server 2005 ha aggiunto la ricompilazione a livello di istruzione, quindi l'impatto è stato minore
Ora, perché un piano con parametri "annusati" è "appiccicoso" rispetto ai parametri mascherati / "sconosciuti", non sono sicuro.
Ho usato il mascheramento dei parametri da SQL Server 2000 per tutti tranne il codice più semplice. Ho notato che è probabile che accada con un codice più complesso. E nel mio vecchio lavoro ho alcuni proc di report che potrei cambiare le impostazioni predefinite dei parametri del piano. Ritengo che l'approccio del "culto delle merci" sia stato più semplice di una richiesta di supporto.
Modifica 2, 12 ott 2011, dopo alcune chat
Il mascheramento dei parametri e OPTIMIZE FOR UNKNOWN hanno lo stesso effetto, per quanto ne so,
il suggerimento è più pulito del mascheramento ma è stato aggiunto con SQL Server 2008.
Lo sniffing dei parametri avviene al momento della compilazione.
WITH RECOMPILE genera un nuovo piano ogni esecuzione. Ciò significa che una scelta errata di valori predefiniti influenzerà il piano. Nel mio ultimo lavoro, ho potuto dimostrarlo facilmente con un codice di report: la modifica delle impostazioni predefinite dei parametri ha modificato il piano indipendentemente dai parametri forniti.
Questo articolo di MS Connect è interessante: utilizzo dell'indice non ottimale all'interno della procedura memorizzata (menzionato in una delle risposte SO di seguito)
- Anche Bob Beauchemin lo menziona
Problemi eccezionali
Lo sniffing si applica ancora con WITH RECOMPILE? Cioè, se l'ottimizzatore sa scartare il piano, mira a riutilizzarlo?
Perché i piani sniffati sono "appiccicosi"?
Collegamenti da SO:
WHEREclausola?