Gagasan Anda bahwa mereka harus melakukan pekerjaan yang sama tidak benar. Bayangkan kumpulan data pengujian ini:
T1
ID
----
1
2
3
4
5
T2
ID
---
1
1
1
2
2
3
DDL
CREATE TABLE dbo.T1 (ID INT NOT NULL);
INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
CREATE TABLE dbo.T2 (ID INT NOT NULL);
INSERT dbo.T2 (ID) VALUES (1), (1), (1), (2), (2), (3);
SELECT *
FROM dbo.T1
WHERE T1.ID IN (SELECT T2.ID FROM dbo.T2);
SELECT T1.*
FROM dbo.T1
INNER JOIN dbo.T2
ON T1.ID = T2.ID;
Hasil
ID
---
1
2
3
ID
---
1
1
1
2
2
3
Hasil Anda hanya sama jika kolom yang Anda cari unik.
CREATE TABLE dbo.T1 (ID INT NOT NULL);
INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
CREATE TABLE dbo.T2 (ID INT NOT NULL);
INSERT dbo.T2 (ID) VALUES (1), (2), (3);
SELECT *
FROM dbo.T1
WHERE T1.ID IN (SELECT T2.ID FROM dbo.T2);
SELECT T1.*
FROM dbo.T1
INNER JOIN dbo.T2
ON T1.ID = T2.ID;
Meski hasilnya sama, rencana eksekusinya tidak. Kueri pertama menggunakan IN
dapat menggunakan anti-semi join, artinya ia mengetahui bahwa data di t2 tidak diperlukan, sehingga segera setelah menemukan satu kecocokan, ia dapat berhenti memindai kecocokan lebih lanjut.
Jika Anda membatasi tabel kedua agar hanya memiliki nilai unik, maka Anda akan melihat paket yang sama:
CREATE TABLE dbo.T1 (ID INT NOT NULL PRIMARY KEY);
INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
CREATE TABLE dbo.T2 (ID INT NOT NULL PRIMARY KEY);
INSERT dbo.T2 (ID) VALUES (1), (2), (3);
SELECT *
FROM dbo.T1
WHERE T1.ID IN (SELECT T2.ID FROM dbo.T2);
SELECT T1.*
FROM dbo.T1
INNER JOIN dbo.T2
ON T1.ID = T2.ID;
Singkatnya, dua kueri tidak akan selalu menghasilkan hasil yang sama, dan mereka tidak akan selalu memiliki rencana yang sama. Itu sangat tergantung pada Indeks Anda dan lebar data/kueri Anda.