sql >> Database teknologi >  >> RDS >> Sqlserver

To selects eller en select + en join i SQL?

Din forestilling om, at de burde gøre det samme arbejde, er ikke sand. Forestil dig dette testsæt af data:

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;

Resultater

ID
---
1
2
3

ID
---
1
1
1
2
2
3

Dine resultater er kun de samme, hvis kolonnen du søger i er 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;

Selvom resultaterne er de samme, er udførelsesplanen det ikke. Den første forespørgsel ved hjælp af IN er i stand til at bruge en anti-semi join, hvilket betyder, at den ved, at dataene i t2 ikke er nødvendige, så så snart den finder et enkelt match, kan den stoppe med at scanne efter yderligere matches.

Hvis du begrænser din anden tabel til kun at have unikke værdier, vil du se den samme 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;

Sammenfattende vil de to forespørgsler ikke altid give de samme resultater, og de vil ikke altid have den samme plan. Det afhænger virkelig af dine indekser og bredden af ​​dine data/forespørgsler.



  1. Sammenlægning af ubrugte tidsrum

  2. Vil du tilsidesætte rækker, der er berørt i SQL Server ved hjælp af ExecuteNonQuery?

  3. mysql_connect() Forskel mellem localhost og 127.0.0.1

  4. Minimering af virkningen af ​​DBCC CHECKDB:DO'er og DONT'er