2014-06-09 23 views
24

Qual è l'ordine predefinito in cui le clausole vengono eseguite in MySQL? È in parte deciso in fase di esecuzione e l'ordine è corretto?Ordine di esecuzione query/clausola MySQL

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

selezionare e gruppo da sovrapporsi leggermente, soprattutto quando si utilizzano le funzioni di aggregazione. non puoi davvero ordinarli rigorosamente in ordine. –

+0

Questa domanda sembra essere fuori tema perché sembra mancare la ricerca – Strawberry

+2

Non ho potuto trovare altrove dove questo argomento è discusso in dettaglio. – ericsicons

risposta

32

L'attuale esecuzione di istruzioni MySQL è un po 'complicato. Tuttavia, lo standard specifica l'ordine di interpretazione degli elementi nella query. Questo è fondamentalmente nell'ordine specificato, anche se credo che HAVING e GROUP BY potuto venire dopo SELECT:

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

Questo è importante per capire come vengono analizzate le query. Non è possibile utilizzare un alias di colonna definito in clausola, ad esempio, perché WHERE viene analizzato prima dello SELECT. D'altra parte, tale alias può essere nella clausola ORDER BY.

Per quanto riguarda l'effettiva esecuzione, ciò è in realtà lasciato all'ottimizzatore. Per esempio:

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

e

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

entrambi hanno l'effetto della ORDER BY non essere eseguito affatto - e quindi non eseguito dopo il GROUP BY (nel primo caso, l'effetto è di rimuovere ordinamento da GROUP BY e nel secondo l'effetto è di fare nient'altro che lo fa già lo GROUP BY).

+1

alias possono essere utilizzati in GROUP BY quindi immagino che viene analizzato dopo selezionare. (SELEZIONA nome come n, conta (nome) FROM gruppo di prova per n) funziona – ericsicons

+0

@ericsicons. . . Grazie. Ho perso questo. –

+0

Sei sicuro 'FROM' è primo? Penso 'WHERE' è il primo, Considerate questo:' SELECT * FROM tabella WHERE false'. Penso che sarà più veloce se la clausola 'WHERE' sarà eseguita prima di' FROM'. – Shafizadeh

0

penso che l'ordine di esecuzione è come questo:

(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

Perché "pensa" che? Qual'è la tua fonte? –

+2

Questo non è l'ordine di esecuzione. Questo è l'ordine di scrittura ... niente a che fare con l'ordine di esecuzione. – pekechis

+0

Penso che 'SELECT' dovrebbe essere il 5 ° –

1

In questo modo è possibile ottenere la vaga idea di come mysql esegue la query di selezione

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; 

Ed ecco l'output dall'alto query MySQL, spero che tu possa capire l'esecuzione di una query mysql SELEZIONA: -

FROM JOIN1 JOIN2 WHERE ON2 ON1 orderBy GROUPBY selezionare dove ON2 ON1 orderBy GROUPBY SELEZIONA avendo avendo