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]
内部テーブルに適切なインデックスが付けられている場合、ここでのサブクエリは厳密な意味で「実行」されていません。
サブクエリはIN
の一部であるため 式の場合、条件はサブクエリにプッシュされ、EXISTS
に変換されます。 。
実際、このサブクエリは各ステップで評価されます:
EXISTS
(
SELECT NULL
FROM [...]
WHERE id = table1.id
)
EXPLAIN EXTENDED
が提供する詳細な説明で実際に確認できます。 。
そのため、DEPENDENT SUBQUERY
と呼ばれています。 :各評価の結果は、table1.id
の値によって異なります。 。サブクエリ自体は相関していません。相関しているのは最適化されたバージョンです。
MySQL
常にEXISTS
を評価します より単純なフィルターの後の句(評価がはるかに簡単で、サブクエリがまったく評価されない可能性があるため)
サブクエリを一度に評価する場合は、クエリを次のように書き直します。
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]
これにより、サブクエリが結合の先頭になります。これは、サブクエリがtable_1
と比較して小さい場合に効率的です。 、サブクエリがtable_1
と比較して大きい場合は、効率が低下します 。
[...].id
にインデックスがある場合 サブクエリで使用されるサブクエリは、INDEX FOR GROUP-BY
を使用して実行されます 。