Was sind die ersten Dinge, die Sie versuchen, wenn Sie eine Abfrage oder eine gespeicherte Prozedur haben, für die eine Leistungsoptimierung erforderlich ist?
sql
sql-server
database
performance
Terrapin
quelle
quelle
Antworten:
Hier ist die praktische Liste der Dinge, die ich immer jemandem gebe, der mich nach der Optimierung fragt.
Wir verwenden hauptsächlich Sybase, aber die meisten Ratschläge gelten allgemein.
SQL Server enthält zum Beispiel eine Vielzahl von Leistungsüberwachungs- / Optimierungsbits. Wenn Sie jedoch nichts dergleichen haben (und vielleicht sogar, wenn Sie dies tun), würde ich Folgendes in Betracht ziehen ...
99% der Probleme, die ich gesehen habe, werden durch das Einfügen zu vieler Tabellen in einen Join verursacht . Die Lösung hierfür besteht darin, die Hälfte des Joins (mit einigen Tabellen) durchzuführen und die Ergebnisse in einer temporären Tabelle zwischenzuspeichern. Führen Sie dann den Rest der Abfrage aus, die in dieser temporären Tabelle verknüpft ist.
Checkliste zur Abfrageoptimierung
#temp
Tabellen sind möglicherweise viel leistungsfähiger als@table
Variablen mit großen Volumes (Tausende von Zeilen).quelle
quelle
Etwas abseits des Themas, aber wenn Sie die Kontrolle über diese Probleme haben ...
High Level und High Impact.
quelle
CREATE INDEX
Stellen Sie sicher, dass für Sie Indizes verfügbar sind
WHERE
undJOIN
Klauseln sind. Dies beschleunigt den Datenzugriff erheblich.Wenn Ihre Umgebung eine ist Data Mart oder ein Warehouse handelt, sollten für fast alle denkbaren Abfragen zahlreiche Indizes vorhanden sein.
In einer Transaktionsumgebung sollte die Anzahl der Indizes geringer und ihre Definitionen strategischer sein, damit die Indexpflege die Ressourcen nicht belastet. (Bei der Indexpflege müssen die Blätter eines Index geändert werden, um eine Änderung der zugrunde liegenden Tabelle wie bei
INSERT, UPDATE,
und widerzuspiegelnDELETE
Operationen .)Beachten Sie auch die Reihenfolge der Felder im Index - je selektiver (höhere Kardinalität) ein Feld ist, desto früher sollte es im Index erscheinen. Angenommen, Sie fragen nach gebrauchten Autos:
Der Preis hat im Allgemeinen eine höhere Kardinalität. Möglicherweise sind nur ein paar Dutzend Farben verfügbar, aber möglicherweise Tausende verschiedener Preisvorstellungen.
idx01
Bietet unter diesen Indexoptionen den schnelleren Pfad, um die Abfrage zu erfüllen:Dies liegt daran, dass weniger Autos den Preis erfüllen als die Farbauswahl, sodass die Abfrage-Engine weitaus weniger Daten zu analysieren hat.
Es ist bekannt, dass zwei sehr ähnliche Indizes nur in der Feldreihenfolge unterschiedlich sind, um Abfragen (Vorname, Nachname) in einem und (Nachname, Vorname) in dem anderen zu beschleunigen.
quelle
Ein Trick, den ich kürzlich gelernt habe, ist, dass SQL Server sowohl lokale Variablen als auch Felder in einer Update-Anweisung aktualisieren kann.
Oder die besser lesbare Version:
Ich habe dies verwendet, um komplizierte Cursor / Joins bei der Implementierung rekursiver Berechnungen zu ersetzen, und habe auch viel an Leistung gewonnen.
Hier sind Details und Beispielcode, die zu fantastischen Leistungsverbesserungen geführt haben: http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal. aspx
quelle
Angenommen, MySQL hier, verwenden Sie EXPLAIN, um herauszufinden, was mit der Abfrage passiert, stellen Sie sicher, dass die Indizes so effizient wie möglich verwendet werden, und versuchen Sie, Dateisortierungen zu beseitigen. Hochleistungs-MySQL: Optimierung, Backups, Replikation und mehr ist ein großartiges Buch zu diesem Thema, ebenso wie MySQL Performance Blog .
quelle
@ Terrapin Es gibt noch ein paar andere Unterschiede zwischen isnull und coalesce, die erwähnenswert sind (neben der ANSI-Konformität, die für mich sehr wichtig ist).
Koaleszenz gegen IsNull
quelle
Wenn Sie in SQL Server ein ODER in einer where-Klausel verwenden, wird die Leistung manchmal erheblich beeinträchtigt. Anstatt den OP zu verwenden, wählen Sie einfach zwei aus und verbinden Sie sie miteinander. Sie erhalten die gleichen Ergebnisse bei 1000-facher Geschwindigkeit.
quelle
Schauen Sie sich die where-Klausel an - überprüfen Sie die Verwendung von Indizes / überprüfen Sie, ob nichts Dummes getan wird
quelle
Ich beginne im Allgemeinen mit den Joins - ich werde jeden einzelnen einzeln aus der Abfrage streichen und die Abfrage erneut ausführen, um eine Vorstellung davon zu bekommen, ob es einen bestimmten Join gibt, mit dem ich ein Problem habe.
quelle
In all meinen temporären Tabellen möchte ich (falls zutreffend) eindeutige Einschränkungen hinzufügen, um Indizes und Primärschlüssel (fast immer) zu erstellen.
quelle
Ich habe es mir zur Gewohnheit gemacht, immer Bindungsvariablen zu verwenden. Es ist möglich, dass Bindungsvariablen nicht helfen, wenn das RDBMS keine SQL-Anweisungen zwischenspeichert. Wenn Sie jedoch keine Bindevariablen verwenden, hat das RDBMS keine Möglichkeit, Abfrageausführungspläne und analysierte SQL-Anweisungen wiederzuverwenden. Die Einsparungen können enorm sein: http://www.akadia.com/services/ora_bind_variables.html . Ich arbeite hauptsächlich mit Oracle, aber Microsoft SQL Server funktioniert fast genauso.
Nach meiner Erfahrung sind Sie es wahrscheinlich nicht, wenn Sie nicht wissen, ob Sie Bindungsvariablen verwenden oder nicht. Wenn Ihre Anwendungssprache sie nicht unterstützt, suchen Sie eine, die dies unterstützt. Manchmal können Sie Abfrage A beheben, indem Sie Bindungsvariablen für Abfrage B verwenden.
Danach spreche ich mit unserem DBA, um herauszufinden, was das RDBMS am meisten schmerzt. Beachten Sie, dass Sie nicht fragen sollten: "Warum ist diese Abfrage langsam?" Das ist so, als würden Sie Ihren Arzt bitten, Ihren Anhang herauszunehmen. Sicher, Ihre Anfrage könnte das Problem sein, aber es ist genauso wahrscheinlich, dass etwas anderes schief geht. Als Entwickler neigen wir dazu, in Codezeilen zu denken. Wenn eine Linie langsam ist, korrigieren Sie diese Linie. Ein RDBMS ist jedoch ein wirklich kompliziertes System, und Ihre langsame Abfrage kann das Symptom eines viel größeren Problems sein.
Viel zu viele SQL-Tuning-Tipps sind Idole des Frachtkultes. In den meisten Fällen hängt das Problem nicht oder nur minimal mit der von Ihnen verwendeten Syntax zusammen. Daher ist es normalerweise am besten, die sauberste Syntax zu verwenden, die Sie können. Anschließend können Sie nach Möglichkeiten suchen, die Datenbank (nicht die Abfrage) zu optimieren. Passen Sie die Syntax nur an, wenn dies fehlschlägt.
Sammeln Sie wie bei jeder Leistungsoptimierung immer aussagekräftige Statistiken. Verwenden Sie keine Wanduhrzeit, es sei denn, es ist die Benutzererfahrung, die Sie einstellen. Schauen Sie sich stattdessen Dinge wie CPU-Zeit, abgerufene Zeilen und von der Festplatte abgelesene Blöcke an. Zu oft optimieren die Leute für das Falsche.
quelle
Erster Schritt: Sehen Sie sich den Abfrageausführungsplan an!
TableScan -> schlechte
NestedLoop -> meh Warnung
TableScan hinter einer NestedLoop -> DOOM!
SET STATISTICS IO ON
SET STATISTICS TIME ON
quelle
Das Ausführen der Abfrage mit WITH (NoLock) ist an meiner Stelle so ziemlich Standard. Jeder, der beim Ausführen von Abfragen an den 10-Gigabyte-Tabellen erwischt wurde, ohne dass diese herausgenommen und erschossen wurden.
quelle
Konvertieren Sie NOT IN-Abfragen nach Möglichkeit in LEFT OUTER JOINS. Wenn Sie beispielsweise alle Zeilen in Tabelle 1 suchen möchten, die von einem Fremdschlüssel in Tabelle 2 nicht verwendet werden, können Sie Folgendes tun:
Aber Sie erhalten damit eine viel bessere Leistung:
quelle
@ DavidM
In SQL Server erhalten Sie mit dem Ausführungsplan dasselbe: Er zeigt Ihnen, welche Indizes betroffen sind usw.
quelle
Indizieren Sie die Tabelle (n) nach den Clms, nach denen Sie filtern
quelle
Nicht unbedingt ein SQL-Leistungstrick an sich, aber definitiv verwandt:
Eine gute Idee wäre, wenn möglich memcached zu verwenden, da es viel schneller wäre, die vorkompilierten Daten direkt aus dem Speicher abzurufen, als sie aus der Datenbank abzurufen. Es gibt auch eine Variante von MySQL, die in Memcached integriert wurde (von Drittanbietern).
quelle
Stellen Sie sicher, dass Ihre Indexlängen so klein wie möglich sind. Auf diese Weise kann die Datenbank mehr Schlüssel gleichzeitig aus dem Dateisystem lesen und so Ihre Joins beschleunigen. Ich gehe davon aus, dass dies mit allen DBs funktioniert, aber ich weiß, dass dies eine spezifische Empfehlung für MySQL ist.
quelle
Ich achte auf:
quelle
Normalerweise die erste Zeile in meinen gespeicherten Prozeduren, es sei denn, ich muss sie tatsächlich verwenden
@@ROWCOUNT
.quelle
Verwenden Sie in SQL Server die Anweisung nolock. Damit kann der Befehl select ausgeführt werden, ohne warten zu müssen - normalerweise werden andere Transaktionen abgeschlossen.
quelle
Entfernen Sie die Cursor überall dort, wo dies nicht erforderlich ist.
quelle
Entfernen Sie Funktionsaufrufe in Sprocs, in denen viele Zeilen die Funktion aufrufen.
Mein Kollege verwendete Funktionsaufrufe (als Beispiel lastlogindate von userid), um sehr breite Datensätze zurückzugeben.
Mit der Optimierung beauftragt, habe ich die Funktionsaufrufe im Sproc durch den Funktionscode ersetzt: Ich habe die Laufzeit vieler Sprocs von> 20 Sekunden auf <1 gesenkt.
quelle
quelle
Ich benutze gerne
Über
Wenn ich die Unterstützung mehrerer Argumente, die Ihnen die Koaleszenz bietet, nicht benötige.
http://blog.falafel.com/2006/04/05/SQLServerArcanaISNULLVsCOALESCE.aspx
quelle
Stellen Sie gespeicherten Prozedurnamen nicht "sp_" voran, da alle Systemprozeduren mit "sp_" beginnen und SQL Server beim Aufrufen Ihrer Prozedur härter suchen muss, um Ihre Prozedur zu finden.
quelle
Schmutzig liest -
Verhindert tote Sperren, bei denen die Transaktionsintegrität nicht unbedingt erforderlich ist (was normalerweise der Fall ist).
quelle
Ich gehe immer zuerst zum SQL Profiler (wenn es sich um eine gespeicherte Prozedur mit vielen Verschachtelungsebenen handelt) oder zum Abfrageausführungsplaner (wenn es sich um einige SQL-Anweisungen ohne Verschachtelung handelt). In 90% der Fälle können Sie das Problem sofort mit einem dieser beiden Tools finden.
quelle