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]
Pokud je vnitřní tabulka správně indexována, poddotaz zde není vůbec "prováděn" v přísném slova smyslu.
Protože dílčí dotaz je součástí IN
výraz, podmínka je vložena do poddotazu a je transformována na EXISTS
.
Ve skutečnosti je tento dílčí dotaz vyhodnocen v každém kroku:
EXISTS
(
SELECT NULL
FROM [...]
WHERE id = table1.id
)
Ve skutečnosti to můžete vidět v podrobném popisu poskytnutém EXPLAIN EXTENDED
.
Proto se nazývá DEPENDENT SUBQUERY
:výsledek každého hodnocení závisí na hodnotě table1.id
. Poddotaz jako takový nekoreluje, koreluje jeho optimalizovaná verze.
MySQL
vždy vyhodnotí EXISTS
klauzule za jednoduššími filtry (protože je mnohem snazší vyhodnotit a existuje pravděpodobnost, že poddotaz nebude vyhodnocen vůbec).
Pokud chcete, aby byl poddotaz vyhodnocen najednou, přepište dotaz takto:
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]
To přinutí poddotaz, aby vedl ve spojení, což je efektivnější, pokud je poddotaz malý ve srovnání s table_1
a méně efektivní, pokud je poddotaz velký ve srovnání s table_1
.
Pokud je na [...].id
index použitý v poddotazu, bude poddotaz proveden pomocí INDEX FOR GROUP-BY
.