An den letzten beiden Mittwochen haben wir eine zweiteilige Webinar-Reihe veranstaltet, die sich mit Fragen der Parametersensitivität befasst:
- Gespeicherte Prozeduren, Parameter, Probleme…
Kimberly L. Tripp und Aaron Bertrand
24. Januar
Verpasst? Registrieren Sie sich jetzt, um es anzusehen! - Parameter-Sniffing mit SentryOne angehen
Aaron Bertrand, Kimberly L. Tripp und Andy Mallon
31. Januar
Verpasst? Jetzt ansehen!
Während beider Webinare kamen einige Fragen auf, und ich dachte, ich stelle sie zusammen und beantworte sie hier (einige der Antworten kamen von Andy während des Webinars).
In einem Problem, das wir kürzlich gesehen haben, sehen wir, dass Pläne sehr schnell aus dem Cache gelöscht werden. Wir führen nichts aus, was Sie beschreiben (
DBCC FREEPROCCACHE
etc.); könnte dies auch durch Speicherdruck verursacht werden?
Ja, Speicherdruck könnte ein Faktor sein (siehe diesen Beitrag), und ich weiß, dass es auch diesbezüglich einige Untersuchungen zu potenziellen Problemen mit der Speicherverwaltung von SQL Server gibt.
Von einem Teilnehmer:„Keine Frage, sondern ein Kommentar an den Benutzer, der fragt, wie oft sein Plan-Cache geleert wird. Das hatten wir auch und tatsächlich war es Speicherdruck. Wir hatten den maximalen Serverspeicher falsch konfiguriert, das war mit der hier erwähnten Formel behoben, und dann ließen wir die Prozedur aus diesem Artikel alle 10 Minuten laufen (wir haben jede Menge dynamisches SQL, das nur einmal verwendet wird)."
Was ist, wenn Sie
OR
verwenden? in der where-Klausel anstelle vonAND
, würde das Problem weiterhin bestehen?
Normalerweise, wenn Sie
OR
verwenden Bei dieser Art von Muster erhalten Sie jedes Mal alle Zeilen, es sei denn, jeder einzelne Parameter ist mit Werten gefüllt, die Zeilen filtern. Dadurch ändert sich die Semantik der Abfrage von „alle diese Dinge müssen wahr sein“ zu „jedes dieser Dinge kann wahr sein“. Dennoch wird der Plan, der für den ersten Satz von Parametern kompiliert wird, immer noch zwischengespeichert und für zukünftige Ausführungen beibehalten, unabhängig davon, ob Ihre KlauselnAND
verwenden oderOR
.
Ist das
1=1
Kennzeichnen Sie einen guten Ansatz? Es ist nicht besser, nur die bereitgestellten Parameter hinzuzufügen und daher das hässliche1=1
zu vermeiden ?
Der
1 = 1
wird von SQL Server praktisch ignoriert, erlaubt jedoch das Hinzufügen aller Bedingungsklauseln mitAND
damit du den *ersten* nicht anders behandeln musst. Hier ist die Alternative:SET @IncludedWhereClauseYet bit = 0; SET @sql = N'SELECT cols FROM dbo.Table'; IF @param1 IS NOT NULL BEGIN IF @IncludedWhereClauseYet = 0 BEGIN SET @sql += N' WHERE '; SET @IncludedWhereClauseYet = 1; END ELSE BEGIN SET @sql += N' AND '; END SET @sql += N' @param1 = @param1'; END IF @param2 IS NOT NULL BEGIN IF @IncludedWhereClauseYet = 0 ... END ...Der
1=1
ermöglicht Ihnen eine Vereinfachung, indem Sie jeder Klausel immerAND
voranstellen können . Der obige Code wird zu:SET @sql = N'SELECT cols FROM dbo.Table WHERE 1 = 1'; IF @param1 IS NOT NULL BEGIN SET @sql += N' AND @param1 = @param1'; END IF @param2 IS NOT NULL BEGIN SET @sql += N' AND @param2 = @param2'; ENDSie könnten vielleicht eine andere Anfangsklausel verwenden, um alle Bedingungen zu vermeiden, wie
WHERE PrimaryKey > 0
oderWHERE PrimaryKey IS NOT NULL
, und dann könnte jede nachfolgende Klausel mitAND
beginnen . Aber1 = 1
, obwohl hässlich, ist harmlos, und meiner Meinung nach ist es nicht weniger hässlich als das Hinzufügen einer *echten*, aber bedeutungslosen Klausel, außer dass eine *echte* Klausel den Plan beeinflussen könnte.Denken Sie daran, dass Sie beim Erstellen von T-SQL-Code mit T-SQL zwei Aspekte von „hässlich“ berücksichtigen müssen – manchmal werden Sie den obigen Code beheben, und manchmal werden Sie die Abfrage beheben, die sich daraus ergibt es. Seien Sie vorsichtig, wenn Sie das eine zugunsten des anderen opfern.
WAS?! Das habe ich total übersehen …
WITH RECOMPILE
. Ich dachte, das würde den Plan zunichte machen, aber es lässt ihn allein für diese Hinrichtung … das ist sehr wichtig zu wissen!
Stellen Sie nur sicher, dass Sie sich auch der Nachteile bewusst sind.
Sehen Sie sich diesen großartigen Beitrag von Paul White an.
Ist
OPTION OPTIMIZE FOR @parametername UNKNOWN
in neueren SQL-Versionen nicht mehr bevorzugt?
Ich glaube nicht, dass es in modernen Versionen besser oder schlechter ist als bei seiner Einführung in SQL Server 2008. Soweit ich weiß, verhält sich dieses Bit trotz aller Änderungen am Optimierer und Kardinalitätsschätzer immer noch gleich.
Wird der Server belastet, wenn ich die Erfassung von Verfahrensstatistiken und Abfragestatistiken in SentryOne aktiviere?
Die Statistiksammlung für Prozeduren und Abfragen sollte standardmäßig aktiviert sein. Jede Datenerfassung ist mit Kosten verbunden, aber SQL Sentry achtet sehr genau darauf, wie viel Kosten durch die Erfassung entstehen.
Die Suche nach RS verwendete es nicht als Restprädikat, es suchte nach etwas anderem, das ich nicht sehen konnte.
Danke, ich werde dieses Beispiel noch einmal durchgehen und separat über die Demos bloggen, wobei ich sicherstellen muss, dass alle relevanten Details enthalten sind, die aus dem Plandiagramm allein nicht ersichtlich sind.
Ist es nicht wahr, dass das Hinzufügen einiger Spalten als
INCLUDE
benötigt wird s machen den Index nicht wirklich effektiver, weil die Schlüsselsuche nicht eliminiert wird? Ich denke, dass sich der Prozentsatz nicht ändern sollte, es sei denn, Sie eliminieren tatsächlich die Schlüsselsuche.
Strenggenommen, ja, das stimmt. Die ursprüngliche Abfrage war ein überragendes schlechtes Beispiel mit
SELECT *
und ein Index, dem eine hoffnungslose Anzahl von Spalten fehlt. Der Punkt, den ich machen wollte, ist, dass die Registerkarte „Indexanalyse“ Sie ermutigt, sowohl (a) die Abfrage zu verbessern als auch (b) den Index abzudecken. Die Punktzahl soll Sie dazu verleiten, eines oder beides zu tun – wenn Sie die Abfrage so ändern, dass Sie weniger Spalten benötigen, kommt der Index auch der Abdeckung der Abfrage näher. Wenn Sie einen neuen, separaten, abdeckenden Index erstellen, haben Sie auch die Informationen darüber, welche Spalten erforderlich sind, um diese spezielle Abfrage abzudecken. Technisch gesehen haben Sie Recht, das Hinzufügen einer Include-Spalte, aber immer noch eine Suche nach 4 anderen, wird diese spezielle Abfrage nicht besser machen und den Index nicht verbessern, aber es zeigt an, dass Sie ' rückt näher. Die Hoffnung ist, dass Sie nicht damit aufhören, nur eine Include-Spalte hinzuzufügen und den Rest ignorieren. Wir wissen nicht, wann Sie aufhören werden, daher weiß ich nicht, ob es eine perfekte Lösung gibt – wir möchten Sie sicherlich nicht entmutigen Benutzer daran hindern, ihre Indizes besser für ihre Abfragen geeignet zu machen.
Warum sehen wir Abfragen, die den Vornamensparameter und den Nachnamensparameter verwenden, zusammengefasst unter einer Anweisung, die nur einen Nachnamensparameter verwendet?
AKTUALISIERUNG: Dies ist beabsichtigt. Die Gruppierung unter Show Totals gruppiert dieselbe Prozedur, die mit allen verschiedenen Parameterkombinationen aufgerufen wird. Sie können es also zuerst verwenden, um zu bestimmen, welche Parameter tendenziell die schlechteste Leistung verursachen, und dann innerhalb dessen untersuchen, ob es eine Datenverzerrung gibt oder nicht. Ein Parameter, der beispielsweise zu einer Suche in einer nicht indizierten Spalte führt, wird wahrscheinlich ziemlich zuverlässig nach oben sprudeln, und Sie können dies in Kombination mit anderen übergebenen Parametern sehen und auch mit allen Aufrufen vergleichen, bei denen dieser Parameter nicht war nicht bestanden.
Nachdem wir das alles gesagt haben, werden wir versuchen, dieses Gruppierungsverhalten zu optimieren, während wir die derzeit laufenden Änderungen für den Top-SQL-Bildschirm abschließen.
Gibt es eine Dokumentation zur Verwendung einer Planhinweisliste? Ich hätte derzeit keine Ahnung, wie das geht.
Dies ist etwas anderes, worüber ich bloggen wollte, aber Microsoft hat in der Zwischenzeit einige Themen hier (und sehen Sie sich alle verwandten Links in der Seitenleiste an).
Muss ich etwas aktivieren, um das Abfrageverlaufsdiagramm zu erhalten?
Nein, dies sollte in allen modernen Versionen der SentryOne-Clientanwendung aktiviert werden. Wenn Sie es nicht sehen, versuchen Sie es mit
Tools > Reset Layout
; Wenn das nicht funktioniert, wenden Sie sich an [email protected].
Gibt es Fälle, in denen der letzte bekannte gute Plan mithilfe des Abfragespeichers erzwungen wird, wenn eine Planregression als schlechte Idee befunden wird? Wird das dazu neigen, Probleme zu verbergen, die besser angegangen werden, indem die Aussage so geändert wird, wie Sie es gezeigt haben?
Das Erzwingen eines Plans ist oft ein letzter Ausweg, und ich neige dazu, es für Fälle zu reservieren, in denen Sie die Anweisung wirklich, wirklich, wirklich nicht korrigieren (oder den Index ändern) können. Das Erzwingen eines Plans kann immer zu falschem Verhalten führen, denn es ist immer noch ein Mensch, der diese Entscheidung trifft, und Sie könnten sie auf der Grundlage schlechter Informationen treffen. Die Regression könnte auf eine Planänderung zurückzuführen sein, aber wenn Sie es als Regression beurteilen, weil die Laufzeit länger war, haben Sie andere mögliche Gründe untersucht? Nehmen wir zum Beispiel an, das System wurde neu gestartet oder es gab ein Failover und einen neuen Plan bekommen, weil der alte entfernt wurde, und vielleicht haben sich die Statistiken in der Zwischenzeit auch geändert, aber jetzt läuft die Abfrage länger, nicht weil der Plan schlechter ist, sondern sondern weil die Puffer leer waren. Also ja, ich würde sicherlich nicht vorschlagen, jeder Regression einen Plan aufzuzwingen.
SentryOne erfasst nicht immer Daten oder Parameter, daher habe ich nicht genügend Informationen. Wie stelle ich sicher, dass SentryOne ständig Parameter und Ausführungspläne erfasst?
Das können Sie wirklich nicht, denn es hängt alles davon ab, wie Ihre Abfragen ausgeführt werden, wie wir sie erfassen und wie schnell sie ausgeführt werden. Häufig werden Ihre Abfragen nicht lange genug ausgeführt, um vollständig erfasst zu werden, und wir müssen uns auf die aggregierten Abfrage-/Prozedurstatistikansichten von SQL Server verlassen, die keine Parameterinformationen erfassen. Sie können die Erfassungseinstellungen für Top SQL Source ändern, um mehr und in kürzeren Intervallen zu erfassen, aber Sie müssen die Menge der erfassten Daten mit der Menge an zusätzlichen Informationen abwägen, die Sie erhalten.
Kann ich die Informationen abfragen, damit ich Berichte automatisieren und generieren kann?
Wir haben nichts vorgefertigtes für Sie, um dies zu tun, aber lassen Sie mich es an das Team zurückgeben und sehen, welche Art von Optionen wir uns einfallen lassen können. Eine Sache, mit der ich für dieses Webinar gespielt habe, war, eine Beratungsbedingung zu erstellen, um die Arten von Regressionen zu erfassen, nach denen wir suchen, aber die Zeit wurde zu einem Faktor.
Wie entscheiden wir, wann wir
OPTION (RECOMPILE)
verwenden , da wir jeden Tag andere Pläne für verschiedene Parameter bekommen?
Ich würde sagen, beginnen Sie mit den Abfragen, die am stärksten mit der Parameterempfindlichkeit schwanken. Wenn ich eine Abfrage habe, die manchmal 2 Sekunden, aber manchmal 30 Sekunden dauert, und eine andere, die zwischen 4 und 6 Sekunden dauert,
werde ich mich auf die erste konzentrieren.
Welche ist besser zu verwenden,
OPTION (RECOMPILE)
oderQUERYTRACEON
, im Fall von Parameter-Sniffing.
Ich bevorzuge
OPTION (RECOMPILE)
aus zwei Gründen. Erstens ist es selbstdokumentierend; Niemand, der den Code liest, wird sich fragen, was er tut, aber nicht jeder, der den Code liest, wird sich TF-Nummern wie 4136 merken können. Zweitens erfordert es keine erhöhten Berechtigungen – versuchen Sie es mitQUERYTRACEON
als Peon.
Ist es möglich, Verfahren zu warnen oder zu melden, die länger als gewöhnlich dauern? Höchstes Interesse an High-Count-Verfahren.
Auf jeden Fall könnten Sie eine beratende Bedingung verwenden, aber es kann ein wenig kompliziert werden, da Sie – für Verfahren, die manchmal sogar unter der Erfassungsschwelle laufen – Snapshots der Verfahrensstatistik DMV vergleichen müssten. Ich habe auch dazu eine Erinnerung an den Blog hinzugefügt, da ich Kunden in der Vergangenheit bei der Implementierung geholfen habe.
Microsoft macht die automatische Optimierung zum Standard für Azure SQL-Datenbank, einschließlich automatischer Plankorrektur. Scheint Ihnen das eine gute Idee zu sein?
Ich behalte mir das Urteil vor, bis ich (oder einige Kunden) damit herumgespielt haben. Die Entscheidung, wie man stimmt, ist für Sterbliche herausfordernd genug; Sterbliche, Software zu schreiben, die sich für Sie einstellt, scheint mindestens genauso herausfordernd zu sein, wenn nicht sogar noch schwieriger. Als Andy diese Frage sah, erwähnte er mir gegenüber, dass sie ihn an SQL Server 2000 erinnerte – das Marketing-Pitch dann war, dass es so selbstoptimierend sei, dass wir keine DBAs mehr brauchen würden. Diese Behauptung ist nicht gut gealtert.
In der Lage zu sein, die beiden Punkte im Diagramm des Abfrageverlaufs auszuwählen und zu vergleichen, wäre schön.
Ich stimme zu.
Bleib dran.