2014-06-09 30 views
24

Jaka jest predefiniowana kolejność, w której klauzule są wykonywane w MySQL? Czy niektóre z nich zdecydowały się w czasie wykonywania i czy ta kolejność jest poprawna?Kolejność wykonywania zapytań/klauzul MySQL

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

wybierz i grupy o nieco zachodzą na siebie, w szczególności gdy stosowane są funkcje kruszywa. nie można tak naprawdę uporządkować ich w porządku. –

+0

To pytanie wydaje się być nie na temat, ponieważ wydaje się brakować badań. – Strawberry

+2

Nie mogłem znaleźć nigdzie indziej, gdzie ten temat jest szczegółowo omówiony. – ericsicons

Odpowiedz

32

Faktyczne wykonanie sprawozdań MySQL jest nieco kłopotliwe. Jednak standard określa kolejność interpretacji elementów w zapytaniu. To jest w zasadzie w porządku, że można określić, chociaż myślę HAVING i GROUP BY może przyjść po SELECT:

  • FROM klauzuli
  • WHERE klauzula
  • SELECT klauzula
  • GROUP BY klauzula
  • HAVING klauzula
  • ORDER BY zdanie

Jest to ważne dla zrozumienia sposobu analizowania zapytań. Nie można użyć aliasu kolumny zdefiniowanego na przykład w klauzuli SELECT w klauzuli WHERE, ponieważ WHERE jest analizowany przed SELECT. Z drugiej strony taki alias może znajdować się w klauzuli ORDER BY.

Co do rzeczywistego wykonania, to tak naprawdę pozostawia się optymalizatorowi. Na przykład:

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

i

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

oba mają wpływ ORDER BY nie są wykonywane w ogóle - i tak nie wykonywane po GROUP BY (w pierwszym przypadku efekt jest usunięcie sortowanie od GROUP BY, aw drugim efektem jest nie robić nic więcej niż GROUP BY już robi).

+1

alias może być użyty w GROUP BY, więc domyślam się, że jest analizowany po wybraniu. (WYBIERZ nazwę jako n, licz (nazwa) Z grupy testowej przez n) działa – ericsicons

+0

@ericsicons. . . Dziękuję Ci. Tęsknie za tym. –

+0

Czy jesteś pewien, że 'FROM' jest pierwszym? Myślę, że "GDZIE" jest pierwszym, Rozważ to: 'WYBIERZ * Z tabeli GDZIE fałsz'. Myślę, że będzie szybciej, jeśli klauzula "WHERE" zostanie wykonana wcześniej niż 'FROM'. – Shafizadeh

0

myślę kolejność wykonywania jest tak:

(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

Dlaczego "myślisz" o tym? Jakie jest twoje źródło? –

+2

To nie jest kolejność wykonywania. To jest kolejność pisania ... nie ma nic wspólnego z zamówieniem. – pekechis

+0

Myślę, że "SELECT" powinno być 5 –

1

W ten sposób można uzyskać przybliżone pojęcie o tym, jak mysql wykonuje kwerendę wybierającą

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; 

I tu jest wyjście z powyższego zapytania mysql, mam nadzieję, że możesz obliczyć wykonanie mysql zapytania SELECT zapytanie: -

Z JOIN1 JOIN2 GDZIE ON2 ON1 orderby GroupBy wybierz, w którym ON2 ON1 orderby GroupBy WYBIERZ PO PO