Orden de ejecución de consulta / cláusula MySQL

¿Cuál es el orden predefinido en el cual las cláusulas se ejecutan en MySQL? ¿Se decide algo en tiempo de ejecución y es correcto este orden?

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

La ejecución real de las declaraciones de MySQL es un poco complicado. Sin embargo, el estándar sí especifica el orden de interpretación de los elementos en la consulta. Esto es básicamente en el orden que especifique, aunque creo que HAVING y GROUP BY podrían venir después de SELECT :

  • Cláusula FROM
  • Cláusula WHERE
  • Cláusula SELECT
  • Cláusula GROUP BY
  • HAVING cláusula
  • Cláusula ORDER BY

Esto es importante para entender cómo se analizan las consultas. No puede usar un alias de columna definido en un SELECT en la cláusula WHERE , por ejemplo, porque WHERE se analiza antes de SELECT . Por otro lado, dicho alias puede estar en la cláusula ORDER BY .

En cuanto a la ejecución real, eso realmente queda en manos del optimizador. Por ejemplo:

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

y

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

ambos tienen el efecto de que ORDER BY no se ejecuta en absoluto, y por lo tanto no se ejecuta después de GROUP BY (en el primer caso, el efecto es eliminar la clasificación de GROUP BY y en el segundo el efecto es no hacer nada más que el GROUP BY ya lo hace).

Así es como puedes obtener la idea aproximada de cómo mysql ejecuta la consulta de selección

 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; 

Y aquí está la salida de la consulta mysql anterior, espero que puedas averiguar la ejecución de mysql de una consulta SELECT : -

DESDE JOIN1 JOIN2 DONDE ON2 ON1 ORDERBY GROUPBY SELECCIONE DONDE ON2 ON1 ORDERBY GROUPBY SELECCIONE TENER TIEMPO

Creo que el orden de ejecución es así:

 (7) SELECT (8) DISTINCT  (1) FROM  (3)  JOIN  (2) ON  (4) WHERE  (5) GROUP BY  (6) HAVING  (9) ORDER BY  (10) LIMIT [, ]