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

IN vs. JOIN s velkými sadami řádků

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 je UNIQUE a b je relativně malý ve srovnání s a , pak se podmínka rozšíří do poddotazu a prostého INNER JOIN se používá (s b vedoucí)

  • Pokud je na b.d index a d není UNIQUE , pak je podmínka také propagována a LEFT SEMI JOIN se používá. Lze jej také použít pro výše uvedenou podmínku.

  • Pokud je index na obou b.d a a.c a jsou velké, pak MERGE SEMI JOIN se používá

  • Pokud v žádné tabulce není žádný index, pak je hashovací tabulka postavena na b a HASH 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.



  1. Jak vytvořit novou databázi s již nainstalovaným rozšířením hstore?

  2. HQL s kontrolou Null pro vztah jedna ku jedné

  3. Jak mohu zkontrolovat, zda existuje tabulka MySQL s PHP?

  4. Transakce by měly být zpracovány v .NET nebo SQL Server?