Su idea de que deberían hacer el mismo trabajo no es cierta. Imagine este conjunto de datos de prueba:
ID
----
1
2
3
4
5
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;
Resultados
ID
---
1
2
3
ID
---
1
1
1
2
2
3
Sus resultados solo son los mismos si la columna en la que está buscando es única.
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;
Aunque los resultados son los mismos, el plan de ejecución no lo es. La primera consulta usando IN
es capaz de usar una combinación anti-semi, lo que significa que sabe que los datos en t2 no son necesarios, así que tan pronto como encuentre una única coincidencia, puede dejar de buscar más coincidencias.
Si restringe su segunda tabla para que solo tenga valores únicos, verá el mismo plan:
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;
En resumen, las dos consultas no siempre arrojarán los mismos resultados y no siempre tendrán el mismo plan. Realmente depende de sus Índices y del ancho de sus datos/consulta.