Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Zwei Selects oder ein Select + ein Join in SQL?

Ihre Vorstellung, dass sie die gleiche Arbeit leisten sollten, ist nicht wahr. Stellen Sie sich diesen Testdatensatz vor:

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;

Ergebnisse

ID
---
1
2
3

ID
---
1
1
1
2
2
3

Ihre Ergebnisse sind nur dann gleich, wenn die Spalte, in der Sie suchen, eindeutig ist.

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;

Obwohl die Ergebnisse dieselben sind, ist es der Ausführungsplan nicht. Die erste Abfrage mit IN ist in der Lage, einen Anti-Semi-Join zu verwenden, was bedeutet, dass es weiß, dass die Daten in t2 nicht benötigt werden, und sobald es eine einzige Übereinstimmung findet, kann es aufhören, nach weiteren Übereinstimmungen zu suchen.

Wenn Sie Ihre zweite Tabelle darauf beschränken, nur eindeutige Werte zu haben, sehen Sie denselben 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;

Zusammenfassend lässt sich sagen, dass die beiden Abfragen nicht immer dieselben Ergebnisse liefern und nicht immer denselben Plan haben. Es hängt wirklich von Ihren Indizes und der Breite Ihrer Daten/Abfrage ab.