Vaše představa, že by měli dělat stejnou práci, není pravdivá. Představte si tuto testovací sadu dat:
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;
Výsledky
ID
---
1
2
3
ID
---
1
1
1
2
2
3
Vaše výsledky jsou stejné pouze v případě, že sloupec, ve kterém hledáte, je jedinečný.
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;
I když jsou výsledky stejné, plán provádění nikoli. První dotaz pomocí IN
dokáže použít anti-semi spojení, což znamená, že ví, že data v t2 nejsou potřeba, takže jakmile najde jedinou shodu, může zastavit vyhledávání dalších shod.
Pokud omezíte svou druhou tabulku tak, aby měla pouze jedinečné hodnoty, uvidíte stejný plán:
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;
Stručně řečeno, tyto dva dotazy neposkytnou vždy stejné výsledky a nebudou mít vždy stejný plán. Opravdu záleží na vašich indexech a šířce vašich dat/dotazu.