Ist die Reihenfolge der Where-Klauseln in SQL von Bedeutung?


121

Angenommen, ich habe eine Tabelle PEOPLEmit 3 Spalten ID, LastName, FirstName. Keine dieser Spalten ist indiziert.
LastNameist einzigartiger und FirstNameweniger einzigartig.

Wenn ich 2 Suchen mache:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F"

Meiner Meinung nach ist das zweite Kriterium schneller, da das eindeutigere Kriterium ( LastName) in der whereKlausel an erster Stelle steht und Datensätze effizienter beseitigt werden. Ich denke nicht, dass der Optimierer klug genug ist, um die erste SQL zu optimieren.

Ist mein Verständnis richtig?


8
Nein, diese Reihenfolge spielt keine Rolle - jeder anständige Abfrageoptimierer wird alle WHERE-Klauseln
prüfen

3
Was waren Ihre Beobachtungen, als Sie diese beiden Aussagen machten? Wie sahen die Ausführungspläne aus?
Conrad Frix

3
Beziehen Sie sich auf ein bestimmtes RDBMS? Es gibt tatsächlich Unterschiede.
Bjoern


Antworten:


101

Nein, diese Reihenfolge spielt keine Rolle (oder sollte zumindest keine Rolle spielen).

Jedes anständige Abfrageoptimierungsprogramm überprüft alle Teile der WHEREKlausel und findet heraus, wie diese Abfrage am effizientesten erfüllt werden kann.

Ich weiß, dass das SQL Server-Abfrageoptimierungsprogramm einen geeigneten Index auswählt - unabhängig davon, in welcher Reihenfolge Sie Ihre beiden Bedingungen haben. Ich gehe davon aus, dass andere RDBMS ähnliche Strategien haben.

Entscheidend ist, ob Sie dafür einen geeigneten Index haben oder nicht!

Im Fall von SQL Server wird wahrscheinlich ein Index verwendet, wenn Sie:

  • ein Index auf (LastName, FirstName)
  • ein Index auf (FirstName, LastName)
  • ein Index für just (LastName)oder just (FirstName)(oder beides)

Wenn Sie jedoch - wiederum für SQL Server - alle Spalten aus einer Tabelle SELECT *abrufen und die Tabelle eher klein ist, besteht eine gute Chance, dass das Abfrageoptimierungsprogramm nur einen Tabellen- (oder Clustered-Index-) Scan durchführt, anstatt sie zu verwenden ein Index (weil das Nachschlagen der vollständigen Datenseite, um alle anderen Spalten abzurufen, sehr schnell zu teuer wird).


Wenn es keine Indizes gibt, könnte op abhängig von den Daten richtig sein. Natürlich wäre es eine seltsame Entscheidung, so etwas ohne Indexe zu tun ...
Tony Hopkinson

@ TonyHopkinson: Das glaube ich nicht - auch ohne Indizes bezweifle ich, dass es überhaupt einen Unterschied gibt. Immerhin: Was kann das RDBMS ohne Indizes wirklich tun, außer einem vollständigen Tabellenscan?
marc_s

2
Interessante Randnotiz mit SQL Server, anscheinend kann die Reihenfolge von NOT EXISTS innerhalb von Prädikaten tatsächlich die Planerstellung
Justin Swartsel

3
Eine seltsame Sache ist, dass bei der ersten Ausführung einer Abfrage die Reihenfolge der Bedingungen in einer WHERE-Klausel eine Rolle spielt! Ich hatte zwei Bedingungen, so etwas wie: WHERE T1.col_1/T2.col_2 > 10 AND T2.col_2 <> 0und bekam einen DIVIDE BY 0Fehler. Nachdem ich die Reihenfolge geändert hatte, wurden die Bedingungen, unter denen die Abfrage erfolgreich ausgeführt wurde. Dann habe ich die Bestellung zurückgeschaltet, damit ich erwarten kann, dass der Fehler erneut auftritt, aber diesmal hat es funktioniert! Am Ende war meine Schlussfolgerung, dass die Bestellung für den ersten Lauf wichtig ist, bis der Ausführungsplan erstellt wird. Danach funktioniert die Bestellung nicht mehr 'egal', weil der Optimierer / Exec-Plan sich darum kümmern wird
Radu Gheorghiu

1
Ich mag es, dass Sie gesagt haben: "... oder zumindest: sollte keine Rolle spielen" - ich stimme vollkommen zu. Manchmal ist es leider wichtig. Ich habe Fälle gesehen, in denen SQL für das Optimierungsprogramm zu komplex war und Dinge wie die Spaltenreihenfolge und die Tabellenverbindungsreihenfolge einen Unterschied machten. Dies hängt vom RDBMS, der Komplexität der SQL-Anweisungen und sogar von der Version ab. Sehr komplexes SQL kann zu schlechten Optimierungsentscheidungen oder zur Verwendung fest codierter Standardeinstellungen im Optimierungscode führen.
Victor Di Leo

19

Die Reihenfolge der WHERE-Klauseln sollte in einer Datenbank, die dem SQL-Standard entspricht, keinen Unterschied machen. Die Reihenfolge der Auswertung ist in den meisten Datenbanken nicht garantiert.

Denken Sie nicht, dass SQL sich um die Reihenfolge kümmert. Folgendes erzeugt einen Fehler in SQL Server:

select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0

Wenn der erste Teil dieser Klausel zuerst ausgeführt würde, würden nur numerische Tabellennamen als Ganzzahlen umgewandelt. Dies schlägt jedoch fehl und liefert ein klares Beispiel dafür, dass SQL Server (wie bei anderen Datenbanken) die Reihenfolge der Klauseln in der WHERE-Anweisung nicht berücksichtigt.


Was hat diese fehlerverursachende Abfrage mit der Reihenfolge der WHERE-Prädikatauswertung zu tun?
Jim

7
@Jim Wenn ISNUMERIC(table_name) = 1zuerst ausgewertet wurde, wird CASTimmer nur für numerische Tabellennamen aufgerufen. Da es jedoch nicht zuerst ausgewertet wird, CASTwird es auch für nicht numerische Tabellennamen ausgewertet, was die Fehlermeldung verursacht.
Hibbelig

2
Hervorragende Klarstellung
neeohw

Nur um sicherzugehen, dass ich überprüft habe, ob das Austauschen der Bedingungen dazu führen würde, dass SQL Server sie umgekehrt behandelt, aber es schlägt in beide Richtungen fehl. Ich denke, dies kann eines von zwei Dingen bedeuten: (1) Es optimiert nicht so gut wie es könnte oder (2) Es ist ein Fehler bei der Kompilierung und SQL versucht nicht einmal, irgendetwas zu vergleichen, sondern rettet vorläufig. Ich vermute, dass es nr ist. 2.
Louis Somers

9

ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3 Reihenfolge der Regelbewertung

...

Wenn die Priorität nicht durch die Formate oder durch Klammern bestimmt wird, wird eine effektive Bewertung der Ausdrücke im Allgemeinen von links nach rechts durchgeführt. Es ist jedoch implementierungsabhängig, ob Ausdrücke tatsächlich von links nach rechts ausgewertet werden, insbesondere wenn Operanden oder Operatoren dazu führen können, dass Bedingungen ausgelöst werden, oder ob die Ergebnisse der Ausdrücke bestimmt werden können, ohne alle Teile des Ausdrucks vollständig auszuwerten.

von hier kopiert


2

Nein, alle RDBMs analysieren zunächst die Abfrage und optimieren sie, indem Sie Ihre where-Klausel neu anordnen.

Abhängig davon, welches RDBM Sie verwenden, können Sie das Ergebnis der Analyse anzeigen (suchen Sie beispielsweise nach dem Erklärungsplan in Oracle).

M.


Dies geschieht anhand von Indizes. Es ist also inhaltlich indirekt.
Tony Hopkinson

1

Ursprüngliche OP-Erklärung

Meiner Meinung nach ist das zweite Kriterium schneller, da das eindeutigere Kriterium (Nachname) in der where-Klausel an erster Stelle steht und Datensätze effizienter beseitigt werden. Ich denke nicht, dass der Optimierer intelligent genug ist, um die erste SQL zu optimieren.

Ich denke, Sie verwechseln dies mit der Auswahl der Spaltenreihenfolge beim Erstellen der Indizes, in denen Sie die selektiveren Spalten an erster Stelle als an zweiter Stelle setzen müssen und so weiter.

Übrigens führt der SQL Server-Optimierer für die beiden oben genannten Abfragen keine Optimierung durch, verwendet jedoch den Trivila-Plan, solange die Gesamtkosten des Plans unter den Parallelitätsschwellenkosten liegen.


0

Es ist wahr, soweit es geht, vorausgesetzt, die Namen sind nicht indiziert. Unterschiedliche Daten würden es jedoch falsch machen. Um herauszufinden, wie dies zu tun ist, was jedes Mal anders sein kann, müsste das DBMS für jede Spalte eine eigene Zählabfrage ausführen und die Zahlen vergleichen, was mehr kosten würde, als nur mit den Schultern zu zucken und damit fortzufahren.

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.