Hinweise zur Abfrageoptimierung in SQL Server 2005/8


13

Ich möchte ein Team über das Schreiben besserer SQL Server-Abfragen aufklären und habe mich gefragt, welche Tipps die besten für die Verbesserung der Leistung sind.

Zum Beispiel hatte ich einmal einen DBA, der darauf bestand, dass count (*) schlechter abschneidet als count (1) (ich habe keine Ahnung, ob sie Recht hatte oder ob es für die neuesten Abfrageoptimierer noch gültig ist).

Welche einfachen Dinge sollte ich dem Team sagen, um zu versuchen, immer zu verwenden oder zu vermeiden? Ich suche im Idealfall nach Dingen, die (a) einen vernünftigen Unterschied machen könnten und (b) direkt sind, 1 - 2 Zeilen zu sagen.

Antworten:


13

Abfrageoptimierung 101

Es gibt keine magische Silberkugel, um Tuning abzufragen, obwohl ich Ihnen einige Tipps und Tricks geben kann. Das erste, was zu tun ist, ist zu verstehen, was tatsächlich hinter den Kulissen vor sich geht. Holen Sie sich ein gutes internes Buch wie das dritte Handbuch des Gurus.

Schlecht durchgeführte Abfragen können zwei grundlegende Ursachen haben: Transaktionsabfragen, die zu lange dauern, und das Schleifen von Stapeljobs (oder Berichten), die zu lange dauern. Ein gutes Zeichen für eine Abfrage, bei der etwas nicht stimmt, ist ein einzelnes Element im Abfrageplan, das 99% der Zeit in Anspruch nimmt.

Transaktionsabfragen

In den meisten Fällen ist eine mangelhafte Transaktionsabfrage eine der folgenden Ursachen:

  • Ein fehlender Index. Sie sehen dies im Abfrageplan - Tabellenscans großer Tabellen in einem Join, der sehr selektiv sein sollte (dh nur wenige Zeilen zurückgeben).

  • Abfrage kann keinen Index verwenden. Wenn die where-Klausel ODER-Bedingungen enthält, eine Verknüpfung zu einem berechneten Wert oder einem anderen Element in der Abfrage hergestellt wird, das nicht zur Verfügung steht, müssen Sie die Abfrage möglicherweise neu schreiben. Kurz gesagt, Sargs sind Abfragevergleichselemente , die mithilfe von Indizes Zeilen entfernen können. Logisches UND, Gleichheit und Ungleichheit (>,> =, <, <= und! =) Sind alle gleichbedeutend. OR ist traditionell nicht sargfähig. Sie können ORs jedoch häufig in gleichwertige Prädikate umwandeln, indem Sie den Sinn von OR-Konstrukten in Konstrukte vom Typ NOT (foo und not bar) umkehren.

  • Ineffiziente Prädikate. Wenn Sie beispielsweise eine where inverschachtelte Unterabfrage referenzieren, prüfen Sie, ob sie als where existsoder als Join neu geschrieben werden kann . Dies kann zu effizienteren Abfrageplänen führen. Hier finden Sie weitere Standardänderungen, die Sie ebenfalls versuchen können. Auch hier sind die Leitfäden des Gurus und andere zu diesem Thema ein guter Ausgangspunkt.

Stapelabfragen

Stapelabfragen sind komplizierter und haben unterschiedliche Optimierungsprobleme. Einige Tipps sind:

  • Indizierung. Dies kann einen großen Unterschied aus dem gleichen Grund wie bei Transaktionsabfragen bedeuten. Ein gutes Zeichen für einen fehlenden Index ist oft ein langer, zermürbender Vorgang (99% des Abfrageplans), der die Maschine nicht zu überfordern scheint.

  • Temporäre Tabellen. Möglicherweise ist es besser, eine Abfrage in mehrere Abfragen aufzuteilen, die temporäre Tabellen füllen. Größere Abfragen bieten dem Optimierer mehr Spielraum für Fehler, obwohl dies früher weniger ein Problem war. Erstellen Sie die temporären Tabellen mit, select intoda dieser Vorgang nur minimal protokolliert wird (viel weniger Protokollaktivität), wodurch die E / A-Belastung verringert wird.

    Beachten Sie, dass temporäre Tabellen in tempdb dieselbe Datenstruktur aufweisen, die das Optimierungsprogramm zum Speichern von Zwischenverknüpfungsergebnissen verwendet, sodass dies keine Leistungseinbußen zur Folge hat. Sie können auch einen Index (einschließlich gruppierter und überdeckender Indizes) für eine temporäre Tabelle erstellen, wodurch die Leistung der Abfragen, die sie lesen, aus den gleichen Gründen verbessert werden kann, aus denen sie Abfragen für statische Tabellen verbessern.

    Übertreiben Sie die temporären Tabellen jedoch nicht, da sie das Zurückverfolgen der Abfrage erschweren können. Testen Sie bei kleineren Tabellen in einer gespeicherten Prozedur, ob Tabellenvariablen hilfreich sind. Hierbei handelt es sich um eine In-Memory-Datenstruktur, sodass Sie einen Leistungsgewinn erzielen können.

  • Clustered und abdeckende Indizes. Dadurch kann die Leistung einer Abfrage verbessert werden, da die Referenzlokalität auf der Festplatte basierend auf einer Gruppierungsspalte erzwungen wird. Ein Clustered-Index kann die Leistung eines Batch-Jobs erheblich beeinflussen.

  • Ineffiziente Prädikate. Dies kann zu Problemen mit Sargs und anderen Suboptimierungsproblemen führen, ähnlich wie bei Transaktionsabfragen.

  • Table Scan ist dein Freund. Entgegen der landläufigen Meinung sind Tabellenscans nicht von Natur aus böse. Im Allgemeinen sind sie ein Zeichen dafür, dass bei einer Transaktionsabfrage etwas nicht stimmt, aber sie sind häufig die effizienteste Methode, um große Batchvorgänge durchzuführen. Wenn Sie mit mehr als ein paar Prozent der Zeilen in einer Tabelle arbeiten, ist ein Tabellenscan häufig die effizienteste Methode, um die Tabelle abzudecken.

  • Verschachtelte Schleifen werden verbunden. Sehen Sie sich an, was das Optimierungsprogramm auf beiden Seiten des Joins ausführt. Dies kann ineffizient sein, wenn Sie zwei große Tabellen auf beiden Seiten eines Join mit verschachtelten Schleifen scannen (z. B.. Erwägen Sie die Verwendung von Clustered-Indizes oder den order byVersuch, den Vorgang in einen Merge-Join zu ändern, oder den Hinweis, einen Hash-Join zu befördern, wenn dies auf einer Seite der Fall ist) klein genug, um dies mit zu tun.

Verriegelung

Das Sperren kann auch zu Leistungsproblemen führen. Wenn Ihr System unter Last schlecht arbeitet, überprüfen Sie die Profiler- und Leistungsindikatoren für Sperren und stellen Sie sicher, dass keine nennenswerten Konflikte vorliegen. sp_who2hat eine 'BlkBy'-Spalte in der Ergebnismenge, die anzeigt, ob und was eine Abfrage blockiert. Außerdem können Profile mit Deadlock-Diagrammereignissen (bei Deadlocking von Abfragen) und Ereignissen im Zusammenhang mit Sperren hilfreich sein, um Probleme mit Sperren zu beheben.


1
+1, da dies einige großartige Informationen zur Leistungsoptimierung sind (ich hatte das Vergnügen, in Kalens Klassen zu sein. Sie weiß, worum es bei ihr geht!). Sie können lediglich einige Informationen zu dynamischen Ansichten hinzufügen.
Wayne

3

Bester Tipp: Verwenden Sie SQL Server 2008 und führen Sie den Aktivitätsmonitor aus, während Ihre Tests ausgeführt werden. Notieren Sie sich die Abfragen, die am längsten dauern / die meisten E / A haben usw. Klicken Sie mit der rechten Maustaste auf diese Abfragen, um die Abfrage und / oder den Ausführungsplan anzuzeigen.

Weiter: Ausführungspläne verstehen lernen.

Weiter: Verwenden Sie den Datenbankoptimierungsassistenten.

Mithilfe dieser Schritte können Sie Ihre eigenen "besten Tipps" generieren.



1

Zunächst Indizierung. Vielen Menschen ist nicht klar, dass Fremdschlüssel nicht automatisch Indizes erhalten. Da sie in Joins verwendet werden, sollten sie fast immer einen Index haben.

Überprüfen Sie alle Cursor genau, um festzustellen, ob sie stattdessen durch satzbasierten Code ersetzt werden können. Ich habe den Code, der stundenlang lief, auf diese Weise in Sekunden geändert.

Vermeiden Sie Unterabfragen. Wenn Sie sie im Code haben, ersetzen Sie sie durch Verknüpfungen oder Verknüpfungen mit abgeleiteten Tabellen.

Stellen Sie sicher, dass Ihre where-Klausel sargeable ist.

Erfahren Sie, wie Sie Ausführungspläne lesen.

Stellen Sie sicher, dass das Büro einige gute Bücher zur Leistungsoptimierung hat.

Tabellenvariablen sind in einigen Fällen besser als temporäre Tabellen, und temporäre Tabellen sind in anderen besser. Wenn Sie sie verwenden müssen, probieren Sie beide aus und finden Sie heraus, welche in diesem speziellen Fall besser funktionieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.