SELECT `table_1`.*
FROM `table_1`
INNER JOIN
`table_2` [...]
INNER JOIN
`table_3` [...]
WHERE `table_1`.`id` IN
(
SELECT `id`
FROM [...]
)
AND [more conditions]
Si la tabla interna está correctamente indexada, la subconsulta aquí no se está "ejecutando" en absoluto en un sentido estricto de la palabra.
Dado que la subconsulta es una parte de una expresión IN
, la condición se inserta en la subconsulta y se transforma en EXISTS
.
De hecho, esta subconsulta se evalúa en cada paso:
EXISTS
(
SELECT NULL
FROM [...]
WHERE id = table1.id
)
en realidad se puede ver que en la descripción detallada proporcionada por EXPLAIN EXTENDED
.
Es por eso que se llama DEPENDENT SUBQUERY
: el resultado de cada evaluación depende del valor de table1.id
. La subconsulta como tal no está correlacionada, es la versión optimizada la que está correlacionada.
MySQL
siempre evalúa la cláusula EXISTS
después de los filtros más simples (ya que son mucho más fáciles de evaluar y existe la probabilidad de que la subconsulta no se evalúe en absoluto).
Si desea que la subconsulta para ser evaluado todos a la vez, vuelve a escribir la consulta como esta:
SELECT table_1.*
FROM (
SELECT DISTINCT id
FROM [...]
) q
JOIN table_1
ON table_1.id = q.id
JOIN table_2
ON [...]
JOIN table_3
ON [...]
WHERE [more conditions]
Esto obliga a la subconsulta para ser líder en la unión, que es más eficiente si la subconsulta es pequeña comparada a table_1
, y menos eficiente si la subconsulta es grande en comparación con table_1
.
Si hay un índice en [...].id
utilizado en la subconsulta, la subconsulta se realizará utilizando un INDEX FOR GROUP-BY
.
Problema al presionar la subconsulta hacia abajo es que esto no es posible si la subconsulta depende de una parte constante de la consulta externa (consulte https://stackoverflow.com/questions/44859809/how-to-optimize-dependent-subquery -with-constant-expression) – andig