sql >> Databáze >  >> RDS >> Sqlserver

Dva výběry nebo jeden výběr + jedno spojení v SQL?

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.



  1. Chyba syntaxe při emulaci uživatele vytvoření, pokud neexistuje

  2. Přejít na postgresql LIKE dotaz

  3. Jak v SQL Serveru zjistím, jaký transakční režim aktuálně používám?

  4. Odstranění duplikátů z výsledku vícenásobného spojení v tabulkách s různými sloupci v MySQL