2009-01-21 1 views
5

Heute noch einmal, ich habe ein großes Problem mit, wie es scheint, Parameter Sniffing in SQL Server 2005.Irgendwann in Ihrer Karriere mit SQL Server springt Parameter Sniffing einfach heraus und greift an?

Ich habe eine Abfrage einige Ergebnisse mit bekannten gute Ergebnisse zu vergleichen. Ich fügte den Ergebnissen und den bekannten guten Ergebnissen eine Spalte hinzu, so dass ich jeden Monat neue Monatsergebnisse auf beiden Seiten laden und nur den aktuellen Monat vergleichen kann. Die neue Spalte steht zuerst im Clustered-Index, sodass neue Monate zum Ende hinzugefügt werden.

füge ich ein Kriterium meiner WHERE Klausel - dieser Code generiert wird, so ist es eine literale Konstante:

WHERE DATA_DT_ID = 20081231 - Welche ist überflüssig, weil alle DATA_DT_ID 20.081.231 sind gerade jetzt.

Leistung geht in den Topf. Von 7 Sekunden, um etwa 1,5 m Zeilen bis 2 Stunden zu vergleichen und nichts abzuschließen. Ausführen des generierten SQL direkt in SSMS - keine SPs.

Ich habe SQL Server seit 12 Jahren verwendet und ich hatte noch nie so viele Probleme mit Parameter-Sniffing wie ich auf diesem Produktionsserver seit Oktober hatte (Build Build 9.00.3068.00). Und in jedem Fall ist es nicht, weil es das erste Mal mit einem anderen Parameter ausgeführt wurde oder die Tabelle geändert wurde. Dies ist eine neue Tabelle und sie wird nur mit diesem Parameter oder keiner WHERE Klausel ausgeführt.

Und nein, ich habe keinen DBA-Zugang, und sie haben mir nicht genug Rechte gegeben, um die Ausführungspläne zu sehen.

Es ist zu dem Punkt, wo ich nicht sicher bin, werde ich in der Lage, mit SQL Server-Benutzer mit nur ein paar Jahren Erfahrung mit diesem System umzugehen.

UPDATE Es stellt sich heraus, dass, obwohl Statistiken behaupten, auf dem neuesten Stand zu sein, das Ausführen von UPDATE STATISTICS WITH FULLSCAN das Problem behebt.

FINAL UPDATE Auch bei der SP neu zu erstellen, unter Verwendung von WITH RECOMPILE und UPDATE STATISTICS, es stellte sich heraus, die Abfrage neu geschrieben werden musste, in einer anderen Art und Weise JOIN mit NULL-Check ein NICHT IN anstelle eines LEFT zu verwenden.

+0

Gibt es hier eine Frage? Klingt wie ein Mecker, Ihre One Where-Klausel verwendet keine Parameter – JoshBerke

+0

Ja, die Frage ist, warum ich nach all den Jahren immer wieder auf diese Probleme stoße - ich denke, die Antwort ist, dass auf diesem Server Statistiken nicht verwaltet werden Genauso wie meine eigenen Server normalerweise oder wie meine Entwicklungs- und Testserver sind. –

+0

Es ist auch mein Verständnis, dass es im Grunde das gleiche Problem ist.Konstanten werden parametrisiert und Ausführungspläne basierend auf den erwarteten Zeilenschätzungen erstellt. –

Antwort

6

Nicht ganz eine Antwort, aber ich werde meine Erfahrung teilen.

Parameter Schnüffeln dauerte ein paar Jahre von SQL Server, um mich zu beißen, als ich zurück zu Developer DBA ging nach Umzug weg, meist DBA Arbeit. Ich verstand mehr über die Engine, wie SQL funktioniert, was am besten dem Client überlassen wurde und ich war ein besserer SQL-Coder.

Zum Beispiel, dynamische SQL oder CURSORs oder einfach nur schlecht SQL-Code wird wahrscheinlich nie leiden Parameter Sniffing. Aber bessere Set-Programmierung oder wie man dynamisches SQL oder eleganter SQL wahrscheinlicher vermeidet.

Ich bemerkte es für komplexe Suchcode (viele Bedingungen) und komplexe Berichte, wo Parameter Standardwerte den Plan betroffen. Wenn ich sehe, wie weniger erfahrene Entwickler diesen Code schreiben würden, erleidet er kein Parameter-Sniffing.

In jedem Fall bevorzuge ich Parameter Maskierung mit WITH RECOMPILE. Das Aktualisieren von Statistiken oder Indizes erzwingt trotzdem eine Neukompilierung. Aber warum die ganze Zeit neu kompilieren? Ich habe an einer Ihrer Fragen woanders geantwortet, mit einem Link, der erwähnt, dass Parameter während der Kompilation beschnüffelt werden, also glaube ich auch nicht daran.

Parametermaskierung ist ein Overhead, ja, aber es ermöglicht dem Optimierer, die Abfrage von Fall zu Fall auszuwerten, anstatt eine erneute Kompilierung durchzuführen. Insbesondere bei der Neukompilierung von SQL Server 2005 auf Anweisungsebene

OPTIMIZE FÜR UNBEKANNT in SQL Server 2008 scheint auch genau das gleiche wie Maskierung zu tun. Mein SQL Server MVP-Kollege und ich verbrachten einige Zeit mit der Untersuchung und kamen zu dieser Schlussfolgerung.

4

Ich vermute, dass Ihr Problem durch Datenstatistiken verursacht wird. Da Sie keinen DBA-Zugriff auf den Server haben, möchte ich Sie bitten, den Datenbankadministrator nach der letzten Aktualisierung der Statistiken zu fragen. Dies kann sich erheblich auf die Leistung auswirken. Es klingt auch so, als ob Ihre Tabellen nicht sehr gut indiziert sind.

Im Grunde fühlt sich dies nicht wie ein Parameter-Sniffing-Problem an, sondern eher ein "gesundes" Datenbankproblem.

Dieser Artikel beschreibt, wie Sie das letzte Mal aktualisiert wurden Statistiken bestimmen können: Statistics Update Time

+0

Die Tabellen sind gut indiziert, aber es ist möglich, dass die Statistiken nicht aktualisiert werden. Danke für die Erinnerung. –

+0

Statistiken werden aktualisiert, wenn Indizes neu erstellt werden. –

2

Ich schließe mich der Kommentar über die Statistiken überprüft - ich mehrere Fälle gesehen, wo die Leistung einer Abfrage hat eine Klippe speziell, weil die abgefallenen Statistiken sind veraltet. Wenn Sie ein Datum in Ihrem PK haben und SQL Server denkt, dass es nur 10 oder 100 Datensätze gibt, die nach einem bestimmten Datum, wenn tatsächlich Tausende vorhanden sind, kann es schrecklich ineffiziente Abfragepläne wählen, weil es denkt, dass Dataset ist viel kleiner als es wirklich ist.

HTH,

  • Andrew
+0

Es stellte sich heraus, dass die Statistiken das Problem waren, aber sie schienen auf dem neuesten Stand zu sein. Ich habe UPDATE STATISTICS mit FULLSCAN ausgeführt und es ist viel besser. Ich werde eine Watchdog-Abfrage einfügen, um sicherzustellen, dass ich die Statistiken aktualisiere, wenn sie zu veraltet sind, auch wenn die automatischen Statistiken der DBAs deaktiviert sind. –

1

Ich hatte eine Produktion Ausgabe genau so. Eine Registerkarte in der Anwendung, die einen gespeicherten Proc aufruft, wird nicht angezeigt. Ich habe eine Spur für den spezifischen Proc ausgeführt und den Anruf gesehen. Die Anwendung hat nach 30 Sekunden eine Zeitüberschreitung, und die Ausführung des Procs dauert ungefähr 40 bis 50 Sekunden (die Prozedur wird genau so ausgeführt, wie sie von der Ablaufverfolgung aufgerufen wird).

Der nächste Schritt war herauszufinden, welche Aussage die Scans verursacht habe, die ich bei der Ausführung des Verfahrens bemerke. Also habe ich den proc ausprobiert, die Prozedursyntax entfernt und Variablen deklariert und im query analyzer ausgeführt. Es ran in 3 Sekunden !!!

Ich schreibe dies, um jemanden da draußen nach Antworten suchen wissen, dass dies in SQL passieren kann. Es stammt aus dem Parameter Sniffing-Problem. Ich konnte diesen Thread nicht ausführen, da ich die Ursache als fehlerhaften Cache-Abfrageplan angegeben habe! Ich habe Beiträge gelesen, in denen sie sagten, dass es mit einem bestimmten Benutzer/Wert passiert. Aber es kann jedem Wert passieren und sobald es beginnt, kann es eine kontinuierliche Sache sein.

Die Lösung für mich war es, die proc und Skript erneut ausführen. Ja. so einfach. Ein alter funktioniert gut. Sie müssen nicht ablegen und neu erstellen. Dadurch wird SQL den zwischengespeicherten Plan aktualisieren, und die Dinge waren in Ordnung. Ich habe nicht herausgefunden, wie man das auf Serverebene deaktiviert. Es ist zu umständlich, alle Procs aufzuräumen. Hoffe, das hilft

+0

Fügen Sie WITH RECOMPILE an das Ende Ihrer Prozedur hinzu, um SQLServer zu erzwingen, einen neuen Ausführungsplan für jeden Lauf zu generieren. – Einstein

+0

Das Endergebnis war, dass die Abfrage tatsächlich neu geschrieben werden musste, um ein etwas anderes Konstrukt zu verwenden. –

Verwandte Themen