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]
Jika tabel bagian dalam diindeks dengan benar, subquery di sini tidak "dilakukan" sama sekali dalam arti kata yang ketat.
Karena subquery adalah bagian dari IN
ekspresi, kondisi didorong ke dalam subquery dan diubah menjadi EXISTS
.
Faktanya, subquery ini dievaluasi pada setiap langkah:
EXISTS
(
SELECT NULL
FROM [...]
WHERE id = table1.id
)
Anda sebenarnya dapat melihatnya dalam deskripsi terperinci yang disediakan oleh EXPLAIN EXTENDED
.
Itulah mengapa disebut DEPENDENT SUBQUERY
:hasil dari setiap evaluasi tergantung pada nilai table1.id
. Subquery seperti itu tidak berkorelasi, itu adalah versi yang dioptimalkan yang berkorelasi.
MySQL
selalu mengevaluasi EXISTS
klausa setelah filter yang lebih sederhana (karena lebih mudah dievaluasi dan ada kemungkinan subquery tidak akan dievaluasi sama sekali).
Jika Anda ingin subkueri dievaluasi sekaligus, tulis ulang kueri seperti ini:
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]
Ini memaksa subquery untuk memimpin dalam penggabungan, yang lebih efisien jika subquery kecil dibandingkan dengan table_1
, dan kurang efisien jika subquerynya besar dibandingkan dengan table_1
.
Jika ada indeks di [...].id
digunakan dalam subquery, subquery akan dilakukan menggunakan INDEX FOR GROUP-BY
.