Aktualizace:
Tento článek na mém blogu shrnuje mou odpověď i mé komentáře k jiným odpovědím a ukazuje skutečné plány realizace:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Tyto dotazy nejsou ekvivalentní. Mohou přinést různé výsledky, pokud vaše tabulka b
není zachován klíč (tj. hodnoty b.d
nejsou jedinečné).
Ekvivalent prvního dotazu je následující:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Pokud b.d
je UNIQUE
a jako takové označeny (s UNIQUE INDEX
nebo UNIQUE CONSTRAINT
), pak jsou tyto dotazy totožné a s největší pravděpodobností budou používat stejné plány, protože SQL Server
je dost chytrý, aby to vzal v úvahu.
SQL Server
může ke spuštění tohoto dotazu použít jednu z následujících metod:
-
Pokud je na
a.c
index ,d
jeUNIQUE
ab
je relativně malý ve srovnání sa
, pak se podmínka rozšíří do poddotazu a prostéhoINNER JOIN
se používá (sb
vedoucí) -
Pokud je na
b.d
index ad
neníUNIQUE
, pak je podmínka také propagována aLEFT SEMI JOIN
se používá. Lze jej také použít pro výše uvedenou podmínku. -
Pokud je index na obou
b.d
aa.c
a jsou velké, pakMERGE SEMI JOIN
se používá -
Pokud v žádné tabulce není žádný index, pak je hashovací tabulka postavena na
b
aHASH SEMI JOIN
se používá.
Ani jeden z těchto metod pokaždé znovu vyhodnotí celý poddotaz.
Další podrobnosti o tom, jak to funguje, najdete v tomto příspěvku na mém blogu:
Jsou zde odkazy pro všechny RDBMS
je z velké čtyřky.