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 "realiza" en absoluto en el sentido estricto de la palabra.
Dado que la subconsulta es parte de un IN
expresión, 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
)
De hecho, puede verlo en la descripción detallada proporcionada por EXPLAIN EXTENDED
.
Por eso 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 el 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 se evalúe de una vez, reescriba la consulta de esta manera:
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 a liderar la combinación, lo que es más eficiente si la subconsulta es pequeña en comparación con table_1
y menos eficiente si la subconsulta es grande en comparación con table_1
.
Si hay un índice en [...].id
usado en la subconsulta, la subconsulta se realizará usando un INDEX FOR GROUP-BY
.