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,dadalahUNIQUEdanbrelatif kecil dibandingkan dengana, kemudian kondisi disebarkan ke subquery danINNER JOINbiasa digunakan (denganbterkemuka) -
Jika ada indeks pada
b.ddandbukanUNIQUE, maka kondisinya juga disebarkan danLEFT SEMI JOINdigunakan. Bisa juga digunakan untuk kondisi di atas. -
Jika ada indeks pada kedua
b.ddana.cdan ukurannya besar, laluMERGE SEMI JOINdigunakan -
Jika tidak ada indeks pada tabel apa pun, maka tabel hash dibangun di atas
bdanHASH SEMI JOINdigunakan.
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.