2014-06-09 17 views
24

Was ist die vordefinierte Reihenfolge, in der die Klauseln in MySQL ausgeführt werden? Wird zur Laufzeit etwas entschieden, und ist diese Reihenfolge korrekt?MySQL Abfrage/Klausel Ausführungsreihenfolge

  • FROM clause
  • WHERE clause
  • GROUP BY clause
  • HAVING clause
  • SELECT clause
  • ORDER BY clause
+1

Auswählen und gruppen durch Überlappung, die jeweils etwas andere besonders wenn Aggregatfunktionen verwendet werden. Sie können diese nicht wirklich streng sortieren. –

+0

Diese Frage scheint off-topic zu sein, weil es scheint, Forschung fehlt – Strawberry

+2

Ich konnte nirgendwo anders finden, wo dieses Thema im Detail diskutiert wird. – ericsicons

Antwort

32

Die tatsächliche Ausführung von MySQL-Anweisungen ist ein bisschen schwierig. Der Standard gibt jedoch die Reihenfolge der Interpretation von Elementen in der Abfrage an. Dies ist im Wesentlichen in der Reihenfolge, die Sie angeben, obwohl ich HAVING denken und GROUP BY könnte kommen nach SELECT:

  • FROM Klausel
  • WHERE Klausel
  • SELECT Klausel
  • GROUP BY Klausel
  • HAVING Klausel
  • ORDER BY Klausel

Dies ist wichtig für das Verständnis, wie Abfragen analysiert werden. Sie können beispielsweise keinen Spaltenalias verwenden, der in SELECT in der WHERE-Klausel definiert ist, weil die WHERE vor der SELECT geparst wird. Auf der anderen Seite kann solch ein Alias ​​in der ORDER BY Klausel sein.

Wie für die tatsächliche Ausführung, das ist wirklich dem Optimierer überlassen. Zum Beispiel:

. . . 
GROUP BY a, b, c 
ORDER BY NULL 

und

. . . 
GROUP BY a, b, c 
ORDER BY a, b, c 

haben sowohl die Wirkung der ORDER BY haupt nicht ausgeführt werden - und so nicht ausgeführt, nachdem die GROUP BY (im ersten Fall die Wirkung zu entfernen ist Sortierung von der GROUP BY und in der zweiten ist der Effekt nichts mehr zu tun, als die GROUP BY bereits tut).

+1

Alias ​​kann in GROUP BY verwendet werden, also denke ich, dass es nach Auswahl geparst wird. (SELECT Name als n, count (Name) FROM Testgruppe von n) funktioniert – ericsicons

+0

@ericsicons. . . Vielen Dank. Das habe ich vermisst. –

+0

Sind Sie sicher, dass "FROM" der erste ist? Ich denke 'WHERE' ist das erste, Betrachten Sie das:' SELECT * FROM Tabelle WHERE false'. Ich denke, es wird schneller, wenn die 'WHERE'-Klausel früher als' FROM' ausgeführt wird. – Shafizadeh

0

ich denke, die Ausführungsreihenfolge ist wie folgt:

(7)  SELECT 
(8)  DISTINCT <select_list> 
(1)  FROM <left_table> 
(3)  <join_type> JOIN <right_table> 
(2)  ON <join_condition> 
(4)  WHERE <where_condition> 
(5)  GROUP BY <group_by_list> 
(6)  HAVING <having_condition> 
(9)  ORDER BY <order_by_condition> 
(10) LIMIT <limit_number>[, <offset_number>] 
+0

Warum "denkst du" das? Was ist deine Quelle? –

+2

Dies ist nicht die Reihenfolge der Ausführung. Das ist die Schreibreihenfolge ... nichts mit der Ausführungsreihenfolge zu tun. – pekechis

+0

Ich denke, SELECT sollte 5. sein –

1

Dies ist, wie Sie die grobe Vorstellung über bekommen kann, wie mysql führt die Auswahlabfrage

DROP TABLE if exists new_table; 

CREATE TABLE `new_table` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`testdecimal` decimal(6,2) DEFAULT NULL, 
PRIMARY KEY (`id`)); 

INSERT INTO `new_table` (`testdecimal`) VALUES ('1234.45'); 
INSERT INTO `new_table` (`testdecimal`) VALUES ('1234.45'); 

set @mysqlorder := ''; 

select @mysqlorder := CONCAT(@mysqlorder," SELECT ") from new_table,(select @mysqlorder := CONCAT(@mysqlorder," FROM ")) tt 
JOIN (select @mysqlorder := CONCAT(@mysqlorder," JOIN1 ")) t on ((select @mysqlorder := CONCAT(@mysqlorder," ON1 ")) or rand() < 1) 
JOIN (select @mysqlorder := CONCAT(@mysqlorder," JOIN2 ")) t2 on ((select @mysqlorder := CONCAT(@mysqlorder," ON2 ")) or rand() < 1) 
where ((select @mysqlorder := CONCAT(@mysqlorder," WHERE ")) or IF(new_table.testdecimal = 1234.45,true,false)) 
group by (select @mysqlorder := CONCAT(@mysqlorder," GROUPBY ")),id 
having (select @mysqlorder := CONCAT(@mysqlorder," HAVING ")) 
order by (select @mysqlorder := CONCAT(@mysqlorder," ORDERBY ")); 

select @mysqlorder; 

Und hier ist der Ausgang von oben MySQL Abfrage, hoffe, Sie können herausfinden, die mysql Ausführung einer SELECT Abfrage: -

FROM JOIN1 JOIN2 WHERE ON2 ON1 ORDERBY GROUPBY SELECT WHERE ON2 ON1 ORDERBY GROUPBY SELECT

Verwandte Themen