Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Posso forçar o mysql a executar a subconsulta primeiro?

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]

Se a tabela interna estiver indexada corretamente, a subconsulta aqui não está sendo "realizada" no sentido estrito da palavra.

Como a subconsulta faz parte de um IN expressão, a condição é enviada para a subconsulta e é transformada em um EXISTS .

Na verdade, essa subconsulta é avaliada em cada etapa:
EXISTS
(
SELECT  NULL
FROM    [...]
WHERE   id = table1.id
)

Você pode realmente vê-lo na descrição detalhada fornecida por EXPLAIN EXTENDED .

É por isso que se chama DEPENDENT SUBQUERY :o resultado de cada avaliação depende do valor de table1.id . A subconsulta como tal não está correlacionada, é a versão otimizada que está correlacionada.

MySQL sempre avalia o EXISTS cláusula após os filtros mais simples (já que eles são muito mais fáceis de avaliar e há uma probabilidade de que a subconsulta não seja avaliada).

Se você quiser que a subconsulta seja avaliada de uma só vez, reescreva a consulta assim:
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]

Isso força a subconsulta a liderar a junção, o que é mais eficiente se a subconsulta for pequena em comparação com table_1 , e menos eficiente se a subconsulta for grande em comparação com table_1 .

Se houver um índice em [...].id usado na subconsulta, a subconsulta será realizada usando um INDEX FOR GROUP-BY .