Orden de ejecución de consultas / cláusulas MySQL


¿Cuál es el orden predefinido en el que se ejecutan las cláusulas en MySQL? ¿Parte de ella se decide en tiempo de ejecución, y este orden es correcto?

  • FROM clause
  • WHERE clause
  • GROUP BY clause
  • HAVING clause
  • SELECT clause
  • ORDER BY clause
Author: User that is not a user, 2014-06-09

3 answers

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

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

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

En cuanto a la ejecución real, eso realmente se deja 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 el ORDER BY no se ejecuta en absoluto -- y por lo tanto no se ejecuta después del GROUP BY (en el primer caso, el efecto es eliminar la ordenación de el GROUP BY y en el segundo el efecto es no hacer nada más que el GROUP BY ya lo hace).

 40
Author: Gordon Linoff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-07 21:40:20

Así es como puede obtener una idea aproximada sobre cómo mysql ejecuta la consulta select

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 pueda averiguar la ejecución mysql de una consulta SELECT: -

DESDE JOIN1 JOIN2 DONDE ON2 ON1 ORDERBY GROUPBY SELECCIONE DONDE ON2 ON1 ORDERBY GROUPBY SELECT HAVING HAVING

 1
Author: Pradeep Kumar Tiwari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-25 19:22:44

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

(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>]
 -2
Author: astarring,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-26 10:31:49