Gibt es einen Leistungsunterschied zwischen diesen beiden Beispielabfragen?
Abfrage 1:
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y'
Abfrage 2;
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
and b.tag = 'Y'
Beachten Sie, dass der einzige Unterschied in der Platzierung der Zusatzbedingung besteht. Der erste verwendet eine WHERE
Klausel und der zweite fügt der ON
Klausel die Bedingung hinzu .
Wenn ich diese Abfragen auf meinem Teradata-System ausführe, sind die EXPLAIN-Pläne identisch und der JOIN-Schritt zeigt die jeweils zusätzliche Bedingung an. Bei dieser SO-Frage zu MySQL schlug eine der Antworten jedoch vor, dass der zweite Stil bevorzugt wird, da die WHERE
Verarbeitung nach dem Herstellen der Verknüpfungen erfolgt.
Gibt es eine allgemeine Regel, nach der Abfragen wie diese codiert werden müssen? Ich vermute, es muss plattformabhängig sein, da es offensichtlich keinen Unterschied für meine Datenbank macht, aber vielleicht ist das nur eine Funktion von Teradata. Und wenn es ist plattformabhängig, würde ich sehr gerne ein paar Dokumentation Referenzen zu erhalten; Ich weiß wirklich nicht, wonach ich suchen soll.
quelle
Antworten:
Gemäß Kapitel 9 (Parser und Optimierer), Seite 172 des Buches Grundlegendes zu MySQL-Interna von Sasha Pachev
Hier ist die Aufteilung der Auswertung einer Abfrage nach folgenden Aufgaben:
ORDER BY
und verwendet werden könnenGROUP BY
.Auf derselben Seite steht:
EPILOG
Aufgrund der vorhandenen Schlüssel, der Datenmenge und des Ausdrucks der Abfrage können MySQL-Verknüpfungen manchmal zu unserem eigenen Wohl (oder um zu uns zurückzukehren) beitragen und Ergebnisse erzielen, die wir nicht erwartet haben und die wir nicht schnell erklären können.
Ich habe schon früher über diese Kuriosität geschrieben
Jan 23, 2013
: Problem mit verschachtelten UPDATE-AbfragenFeb 22, 2011
: Problem mit MySQL-Unterabfrageweil der MySQL Query Optimizer bestimmte Schlüssel während der Auswertung der Abfrage verwerfen könnte.
@ Phils Kommentar hilf mir, diese Antwort zu posten (+1 für @ Phils Kommentar)
@ ypercubes Kommentar (+1 auch für diesen) ist eine kompakte Version meines Posts, da MySQLs Query Optimizer primitiv ist. Leider muss es sein, da es sich um externe Speicher-Engines handelt.
FAZIT
Was Ihre eigentliche Frage betrifft, würde das MySQL-Abfrageoptimierungsprogramm die Leistungsmetriken jeder Abfrage ermitteln, wenn diese erledigt ist
Wahrscheinlich müssten Sie die Ausführungsreihenfolge erzwingen, indem Sie die Abfrage neu schreiben (refactoring)
Hier ist die erste Abfrage, die Sie gegeben haben
Versuchen Sie es neu zu schreiben, um zuerst das WHERE auszuwerten
Das würde definitiv den EXPLAIN-Plan ändern. Es könnte zu besseren oder schlechteren Ergebnissen führen.
Ich habe einmal eine Frage in StackOverflow beantwortet, in der ich diese Technik angewendet habe. Das EXPLAIN war horrend, aber die Aufführung war Dynamit. Es funktionierte nur, weil die richtigen Indizes vorhanden waren und LIMIT in einer Unterabfrage verwendet wurde .
Ähnlich wie bei den Aktienkursen gelten bei Abfragen und dem Versuch, sie auszudrücken, Beschränkungen, die Ergebnisse können variieren und die Wertentwicklung in der Vergangenheit ist kein Hinweis auf zukünftige Ergebnisse.
quelle
Für Oracle haben wir, da mySQL eine lange Beschreibung hatte, zwei Möglichkeiten, den Optimierer wirksam einzusetzen.
Erstens ist die regelbasierte Optimierung (oder RBO). Oracle hat 15 festgelegte Regeln, denen jede Abfrage, die es analysiert, in einer festgelegten Reihenfolge zu folgen versucht. Wenn aus Regel 1 keine optimierte Abfrage generiert werden kann, wird mit Regel 2 fortgefahren, bis Regel 15 erreicht wird.
Weitere Informationen: https://docs.oracle.com/cd/B10500_01/server.920/a96533/rbo.htm
Diese betreffen Oracle RDBMS-Kernel ab 11.1, die nicht in Cost Based Optimizer (auch bekannt als CBO) konvertiert wurden. Oracle 11.2 und höher erfordern das CBO-Optimierungsprogramm, können jedoch bestimmte SQL-IDs zur Optimierung in der alten RBO-Methode zwingen, wenn der Benutzer dies wünscht.
Das CBO für Oracle 11.1+ erstellt stattdessen mehrere Ausführungspläne für dieselbe SQL-ID und führt denjenigen mit den geringsten erwarteten Gesamtkosten aus. Es nutzt einen Großteil der Logik von RBO, analysiert jedoch Tabellenstatistiken, um dynamische Ausführungsplankosten für jeden Vorgang zu erstellen, den die DB ausführen muss, um dem Endbenutzer ihre Daten bereitzustellen. Das Ausführen vollständiger Tabellensuchen an sehr großen Tabellen ist sehr kostspielig. Das Ausführen vollständiger Tabellenscans für eine Tabelle mit 10 Zeilen ist günstig. In der RBO wurden diese als gleichberechtigt angesehen.
Weitere Informationen: https://oracle-base.com/articles/misc/cost-based-optimizer-and-database-statistics
Für Ihr spezielles Abfragebeispiel: Oracle würde die Informationen wahrscheinlich analysieren, um unterschiedliche Ausführungspläne zu erstellen, und daher ist einer technisch besser als der andere. Dies kann jedoch ein minimaler Unterschied sein. Oracle RBO und CBO möchten eine Abfrage 1 mehr, da sie bei einem Join unter weniger Bedingungen ausgeführt wird und dann eine bestimmte Spalte aus der temporären Tabelle herausfiltert, die sie bei dem Join erstellt hat.
quelle
Wenn Sie zwei Abfragen haben und diese für gleichwertig halten, kann Folgendes passieren:
Es gibt verschiedene Ausführungspläne. Wir haben hier zwei Unterfälle.
2.1 Die Abfragen haben unterschiedliche Ausführungspläne, aber beide Pläne sind gleich gut. Das ist auch gut so. Es ist nicht erforderlich, dass für äquivalente Abfragen derselbe Plan generiert wird. Die Leistung sollte aber gleich sein. Und wieder hoffen wir, dass es das bestmögliche ist.
2.2 Die Abfragen haben unterschiedliche Ausführungspläne und ein Plan ist besser als der andere. Wieder haben wir Unterfälle:
2.2.1 Die Pläne sind unterschiedlich, da die Abfragen nicht gleichwertig sind. Prüfen Sie daher sorgfältig, ob sie wirklich gleichwertig sind. In Ihrem Fall sind sie wirklich gleichwertig.
2.2.2 Die Pläne sind unterschiedlich, aber die Abfragen sind gleichwertig. Dies bedeutet, dass der Optimierer nicht ausreichend ausgereift ist. In einer perfekten Welt mit perfekten Optimierern sollte dies nicht passieren. Also ja, es ist plattformabhängig und Sie müssen plattformspezifische Dokumente studieren, um herauszufinden, warum dies geschieht.
2.2.3 Die Pläne sind unterschiedlich, die Abfragen sind äquivalent, die Datenbanksoftware hat einen Fehler.
quelle