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
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).
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
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>]
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