sql >> Base de Datos >  >> RDS >> Mysql

¿Puedo obligar a mysql a realizar una subconsulta primero?

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 .