Вашето мнение, че те трябва да вършат една и съща работа, не е вярно. Представете си този тестов набор от данни:
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;
Резултати
ID
---
1
2
3
ID
---
1
1
1
2
2
3
Вашите резултати са еднакви само ако колоната, в която търсите, е уникална.
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;
Въпреки че резултатите са същите, планът за изпълнение не е. Първата заявка, използваща IN
може да използва анти-полусъединяване, което означава, че знае, че данните в t2 не са необходими, така че веднага щом намери едно съвпадение, може да спре сканирането за други съвпадения.
Ако ограничите втората си таблица да има само уникални стойности, тогава ще видите същия план:
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;
В обобщение, двете заявки не винаги ще дадат еднакви резултати и не винаги ще имат един и същ план. Това наистина зависи от вашите индекси и ширината на вашите данни/заявка.