Übliche Verdächtige:
- Konstanten in Ad-hoc, Parameter im Code
- Nichtübereinstimmung der Datentypen im Code
- Parameter schnüffeln
Punkt 1: Der Optimierer kann den besten Plan für die Konstanten auswählen.
Ändern Sie die Konstanten = ändern Sie den Plan. Ein parametrisierter Plen ist resuierbar
Punkt 2 führt implizite Konvertierungen ein, da der Datentyp Vorrang hat,
z. B. die varchar-Spalte im Vergleich zum Parameter nvarchar
Punkt 3: Verwenden Sie die Parametermaskierung oder OPTIMIEREN SIE FÜR UNBEKANNT.
Bearbeiten: Zum Testen: Speichern Sie den gespeicherten Prozess, führen Sie sp_updatestats aus und führen Sie ihn erneut aus. Dadurch werden zwischengespeicherte Pläne ungültig, was besser ist als das Löschen des Plan-Cache
Bearbeiten: nach dem Kommentar von jcolebrand
Sie können das Schnüffeln auf verschiedene Arten deaktivieren. Die wichtigsten 3 sind
- RECOMPILE. Das ist dumm IMO.
- OPTIMIEREN (sic) FÜR UNBEKANNT
- Parametermaskierung
Parametermaskierung:
DECLARE @MaskedParam varchar(10)
SELECT @MaskedParam = @SignaureParam
SELECT...WHERE column = @MaskedParam
Die Maskierung und der OPTIMIZE-Hinweis haben den gleichen Effekt (möglicherweise aus verschiedenen Gründen). Das heißt, der Optimierer muss Statistiken verwenden und die Datenverteilung ( Hinweis: wird noch von Mark Storey-Smith getestet ) die Parameter nach ihren eigenen Vorzügen bewerten . , anstatt was sie zuletzt angerufen hatten. Der Optimierer kann neu kompilieren oder nicht. SQL Server 2005 fügte eine Neukompilierung auf Anweisungsebene hinzu, sodass weniger Auswirkungen auftraten
Ich bin mir nicht sicher, warum ein Plan mit "beschnüffelten" Parametern im Vergleich zu maskierten / "unbekannten" Parametern "klebrig" ist.
Ich habe seit SQL Server 2000 die Parametermaskierung für alle außer dem einfachsten Code verwendet. Ich habe festgestellt, dass dies bei komplexerem Code wahrscheinlich vorkommt. Und bei meinem alten Job habe ich einige Berichtsprozesse, dass ich die Standardeinstellungen der Planparameter ändern könnte. Ich denke, der "Frachtkult" -Ansatz war einfacher als ein Support-Anruf.
Edit 2, 12. Oktober 2011, nach einigem Chat
Die Parametermaskierung und OPTIMIZE FOR UNKNOWN haben, soweit ich das beurteilen kann, den gleichen Effekt.
Der Hinweis ist sauberer als die Maskierung, wurde jedoch mit SQL Server 2008 hinzugefügt.
Das Parameter-Sniffing erfolgt zur Kompilierungszeit.
WITH RECOMPILE generiert bei jeder Ausführung einen neuen Plan. Dies bedeutet, dass eine schlechte Auswahl der Standardeinstellungen den Plan beeinflusst. Bei meinem letzten Job konnte ich dies leicht mit einem Berichtscode demonstrieren: Durch Ändern der Parameterstandards wurde der Plan unabhängig von den angegebenen Parametern geändert.
Dieser MS Connect-Artikel ist interessant: Suboptimale Indexverwendung innerhalb der gespeicherten Prozedur (in einer der folgenden SO-Antworten erwähnt)
- Bob Beauchemin erwähnt es auch
Offene Fragen
Gilt das Schnüffeln immer noch mit WITH RECOMPILE? Das heißt, wenn der Optimierer weiß, dass er den Plan verwerfen muss, zielt er auf eine Wiederverwendung ab?
Warum sind schnüffelnde Pläne "klebrig"?
Links von SO:
WHERE
Klausel?