Pembaruan:
Artikel di blog saya ini merangkum jawaban saya dan komentar saya untuk jawaban lain, dan menunjukkan rencana eksekusi yang sebenarnya:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Kueri ini tidak setara. Mereka dapat memberikan hasil yang berbeda jika tabel Anda b
bukan kunci yang dipertahankan (yaitu nilai b.d
tidak unik).
Setara dengan kueri pertama adalah sebagai berikut:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Jika b.d
adalah UNIQUE
dan ditandai seperti itu (dengan UNIQUE INDEX
atau UNIQUE CONSTRAINT
), maka kueri ini identik dan kemungkinan besar akan menggunakan paket yang identik, karena SQL Server
cukup pintar untuk mempertimbangkan hal ini.
SQL Server
dapat menggunakan salah satu metode berikut untuk menjalankan kueri ini:
-
Jika ada indeks di
a.c
,d
adalahUNIQUE
danb
relatif kecil dibandingkan dengana
, kemudian kondisi disebarkan ke subquery danINNER JOIN
biasa digunakan (denganb
terkemuka) -
Jika ada indeks pada
b.d
dand
bukanUNIQUE
, maka kondisinya juga disebarkan danLEFT SEMI JOIN
digunakan. Bisa juga digunakan untuk kondisi di atas. -
Jika ada indeks pada kedua
b.d
dana.c
dan ukurannya besar, laluMERGE SEMI JOIN
digunakan -
Jika tidak ada indeks pada tabel apa pun, maka tabel hash dibangun di atas
b
danHASH SEMI JOIN
digunakan.
Tidak keduanya dari metode ini mengevaluasi kembali seluruh subquery setiap kali.
Lihat entri ini di blog saya untuk detail lebih lanjut tentang cara kerjanya:
Ada tautan untuk semua RDBMS
dari empat besar.