Database
 sql >> Datenbank >  >> RDS >> Database

Zehn häufige Bedrohungen für die Qualität von Ausführungsplänen

Die Qualität eines Ausführungsplans hängt stark von der Genauigkeit der geschätzten Anzahl von Zeilen ab, die von jedem Planoperator ausgegeben werden. Wenn die geschätzte Zeilenanzahl erheblich von der tatsächlichen Zeilenanzahl abweicht, kann dies erhebliche Auswirkungen auf die Qualität des Ausführungsplans einer Abfrage haben. Eine schlechte Planqualität kann für übermäßige E/A, überhöhte CPU, Speicherauslastung, verringerten Durchsatz und verringerte Gesamtparallelität verantwortlich sein.

Mit „Planqualität“ – ich spreche davon, dass SQL Server einen Ausführungsplan generiert, der zu physischen Operatorauswahlen führt, die den aktuellen Status der Daten widerspiegeln. Indem solche Entscheidungen auf der Grundlage genauer Daten getroffen werden, besteht eine bessere Chance, dass die Abfrage ordnungsgemäß ausgeführt wird. Die Schätzwerte der Kardinalität werden als Eingabe für die Operatorkostenrechnung verwendet, und wenn die Werte zu weit von der Realität entfernt sind, können die negativen Auswirkungen auf den Ausführungsplan deutlich werden. Diese Schätzungen werden in die verschiedenen Kostenmodelle eingespeist, die der Abfrage selbst zugeordnet sind, und Schätzungen fehlerhafter Zeilen können sich auf eine Vielzahl von Entscheidungen auswirken, darunter Indexauswahl, Such- vs. Scanvorgänge, parallele vs. serielle Ausführung, Auswahl des Join-Algorithmus, innerer vs. äußerer physischer Join Auswahl (z. B. Build vs. Probe), Spool-Generierung, Bookmark-Lookups vs. vollständiger Cluster- oder Heap-Tabellenzugriff, Stream- oder Hash-Aggregat-Auswahl und ob eine Datenänderung einen Wide- oder Narrow-Plan verwendet oder nicht.

Nehmen wir als Beispiel an, Sie haben das folgende SELECT Abfrage (unter Verwendung der Credit-Datenbank):

SELECT
  m.member_no,
  m.lastname,
  p.payment_no,
  p.payment_dt,
  p.payment_amt
FROM dbo.member AS m
INNER JOIN dbo.payment AS p
ON m.member_no = p.member_no;

Ist die folgende Planform basierend auf der Abfragelogik das, was Sie erwarten würden?

Und was ist mit diesem alternativen Plan, bei dem wir anstelle einer verschachtelten Schleife einen Hash-Match haben?

Die „richtige“ Antwort hängt von einigen anderen Faktoren ab – aber ein wichtiger Faktor ist die Anzahl der Zeilen in jeder der Tabellen. In einigen Fällen ist ein physischer Join-Algorithmus besser geeignet als der andere – und wenn die anfänglichen Annahmen zur Kardinalitätsschätzung nicht korrekt sind, verwendet Ihre Abfrage möglicherweise einen nicht optimalen Ansatz.

Identifizieren Probleme mit der Kardinalitätsschätzung sind relativ einfach. Wenn Sie einen tatsächlichen Ausführungsplan haben, können Sie die geschätzten mit den tatsächlichen Zeilenanzahlwerten für Operatoren vergleichen und nach Schiefen suchen. Der SQL Sentry Plan Explorer vereinfacht diese Aufgabe, indem er Ihnen ermöglicht, tatsächliche und geschätzte Zeilen für alle Operatoren auf einer einzigen Planbaum-Registerkarte anzuzeigen, anstatt den Mauszeiger über die einzelnen Operatoren im grafischen Plan bewegen zu müssen:

Nun, Verzerrungen führen nicht immer zu Plänen mit schlechter Qualität, aber wenn Sie Leistungsprobleme mit einer Abfrage haben und solche Verzerrungen im Plan sehen, ist dies ein Bereich, der näher untersucht werden sollte.

Die Identifizierung von Problemen mit der Kardinalitätsschätzung ist relativ einfach, die Lösung jedoch häufig nicht. Es gibt eine Reihe von Ursachen dafür, warum Probleme mit der Kardinalitätsschätzung auftreten können, und ich werde in diesem Beitrag zehn der häufigsten Gründe behandeln.

Fehlende oder veraltete Statistiken

Von allen Gründen für Probleme mit der Kardinalitätsschätzung ist dies derjenige, auf den Sie hoffen zu sehen, da es oft am einfachsten zu adressieren ist. In diesem Szenario fehlen Ihre Statistiken oder sind veraltet. Möglicherweise haben Sie Datenbankoptionen für die automatische Statistikerstellung und -aktualisierung deaktiviert, "keine Neuberechnung" für bestimmte Statistiken aktiviert oder Sie haben Tabellen, die so groß sind, dass Ihre automatischen Statistikaktualisierungen einfach nicht häufig genug erfolgen.

Sampling-Probleme

Es kann sein, dass die Genauigkeit des Statistikhistogramms unzureichend ist – zum Beispiel, wenn Sie eine sehr große Tabelle mit erheblichen und/oder häufigen Datenverzerrungen haben. Möglicherweise müssen Sie Ihre Standardstichprobe ändern, oder wenn selbst das nicht hilft, untersuchen Sie dies anhand separater Tabellen, gefilterter Statistiken oder gefilterter Indizes.

Verborgene Spaltenkorrelationen

Der Abfrageoptimierer geht davon aus, dass Spalten innerhalb derselben Tabelle unabhängig sind. Wenn Sie beispielsweise eine Stadt- und Bundeslandspalte haben, wissen wir vielleicht intuitiv, dass diese beiden Spalten korreliert sind, aber SQL Server versteht dies nicht, es sei denn, wir helfen ihm mit einem zugeordneten mehrspaltigen Index oder mit manuell erstellten mehrspaltigen Spaltenstatistik. Ohne dem Optimierer bei der Korrelation zu helfen, kann die Selektivität Ihrer Prädikate übertrieben sein.

Unten ist ein Beispiel für zwei korrelierte Prädikate:

SELECT 
  lastname,
  firstname
FROM dbo.member
WHERE city = 'Minneapolis'
AND state_prov - 'MN';

Ich weiß zufällig, dass 10 % unserer 10.000 Zeilen member Tabelle sind für diese Kombination geeignet, aber der Abfrageoptimierer geht davon aus, dass es sich um 1 % der 10.000 Zeilen handelt:

Vergleichen Sie dies nun mit der entsprechenden Schätzung, die ich nach dem Hinzufügen von mehrspaltigen Statistiken sehe:

Spaltenvergleiche innerhalb der Tabelle

Beim Vergleichen von Spalten innerhalb derselben Tabelle können Probleme mit der Kardinalitätsschätzung auftreten. Dies ist ein bekanntes Problem. Wenn Sie dies tun müssen, können Sie die Kardinalitätsschätzungen der Spaltenvergleiche verbessern, indem Sie stattdessen berechnete Spalten verwenden oder die Abfrage neu schreiben, um Self-Joins oder allgemeine Tabellenausdrücke zu verwenden.

Verwendung von Tabellenvariablen

Verwenden Sie häufig Tabellenvariablen? Tabellenvariablen zeigen eine Kardinalitätsschätzung von „1“ – was bei einer kleinen Anzahl von Zeilen möglicherweise kein Problem darstellt, bei großen oder volatilen Ergebnismengen jedoch die Qualität des Abfrageplans erheblich beeinträchtigen kann. Unten sehen Sie einen Screenshot der Schätzung eines Operators von 1 Zeile im Vergleich zu den tatsächlichen 1.600.000 Zeilen aus @charge Tabellenvariable:

Wenn dies Ihre Hauptursache ist, sind Sie gut beraten, nach Möglichkeit Alternativen wie temporäre Tabellen und/oder permanente Staging-Tabellen zu prüfen.

Skalare und MSTV-UDFs

Ähnlich wie Tabellenvariablen sind Tabellenwert- und Skalarfunktionen mit mehreren Anweisungen aus Sicht der Kardinalitätsschätzung eine Blackbox. Wenn Sie aufgrund dessen auf Probleme mit der Planqualität stoßen, ziehen Sie Inline-Tabellenfunktionen als Alternative in Betracht – oder ziehen Sie sogar die Funktionsreferenz vollständig heraus und verweisen Sie nur direkt auf Objekte.

Unten sehen Sie einen geschätzten Plan im Vergleich zum tatsächlichen Plan bei Verwendung einer Tabellenwertfunktion mit mehreren Anweisungen:

Datentypprobleme

Probleme mit impliziten Datentypen in Verbindung mit Such- und Verknüpfungsbedingungen können zu Problemen mit der Kardinalitätsschätzung führen. Sie können auch heimlich Ressourcen auf Serverebene (CPU, I/O, Arbeitsspeicher) verschlingen, daher ist es wichtig, sie wann immer möglich anzugehen.

Komplexe Prädikate

Sie haben dieses Muster wahrscheinlich schon einmal gesehen – eine Abfrage mit einem WHERE -Klausel, die jede Tabellenspaltenreferenz in verschiedene Funktionen, Verkettungsoperationen, mathematische Operationen und mehr verpackt hat. Und obwohl nicht jede Funktionsumschließung korrekte Kardinalitätsschätzungen ausschließt (z. B. für LOWER , UPPER und GETDATE ) gibt es viele Möglichkeiten, Ihr Prädikat so weit zu begraben, dass der Abfrageoptimierer keine genauen Schätzungen mehr vornehmen kann.

Abfragekomplexität

Sind Ihre Abfragen, ähnlich wie bei vergrabenen Prädikaten, außerordentlich komplex? Mir ist klar, dass „komplex“ ein subjektiver Begriff ist, und Ihre Einschätzung kann variieren, aber die meisten werden zustimmen, dass das Verschachteln von Ansichten innerhalb von Ansichten innerhalb von Ansichten, die auf überlappende Tabellen verweisen, wahrscheinlich nicht optimal ist – insbesondere in Verbindung mit mehr als 10 Tabellenverknüpfungen, Funktionsreferenzen und begrabene Prädikate. Obwohl der Abfrageoptimierer eine bewundernswerte Arbeit leistet, ist er keine Zauberei, und wenn Sie erhebliche Schiefe haben, kann die Komplexität der Abfrage (Abfragen mit dem Schweizer Taschenmesser) es sicherlich nahezu unmöglich machen, genaue Zeilenschätzungen für Operatoren abzuleiten.

Verteilte Abfragen

Verwenden Sie verteilte Abfragen mit Verbindungsservern und stellen Sie erhebliche Probleme bei der Kardinalitätsschätzung fest? Überprüfen Sie in diesem Fall unbedingt die Berechtigungen, die dem verknüpften Serverprinzipal zugeordnet sind, der für den Zugriff auf die Daten verwendet wird. Ohne das Minimum db_ddladmin Datenbankrolle für das verknüpfte Serverkonto festgelegt haben, kann diese fehlende Sichtbarkeit für Remote-Statistiken aufgrund unzureichender Berechtigungen die Ursache für Ihre Probleme bei der Kardinalitätsschätzung sein.

Und es gibt noch andere...

Es gibt andere Gründe, warum Kardinalitätsschätzungen verzerrt sein können, aber ich glaube, ich habe die häufigsten behandelt. Der entscheidende Punkt ist, auf die Schiefe in Verbindung mit bekannten Abfragen mit schlechter Leistung zu achten. Gehen Sie nicht davon aus, dass der Plan basierend auf genauen Zeilenanzahlbedingungen generiert wurde. Wenn diese Zahlen verzerrt sind, müssen Sie zuerst versuchen, das Problem zu beheben.