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

Klauzule WHERE je lepší provést před IN a JOIN nebo po

V případě INNER JOIN nebo tabulky vlevo v LEFT JOIN v mnoha případech optimalizátor zjistí, že je lepší provést nejprve jakékoli filtrování (nejvyšší selektivita), než skutečně provést jakýkoli typ fyzického spojení – takže jsou zjevně fyzické pořadí operací, které jsou lepší.

Do jisté míry to můžete někdy ovládat (nebo do toho zasahovat) se svým SQL, například pomocí agregátů v poddotazech.

Logické pořadí zpracování omezení v dotazu lze transformovat pouze podle známých invariantních transformací.

Takže:

SELECT *
FROM a
INNER JOIN b
    ON a.id = b.id
WHERE a.something = something
    AND b.something = something

je stále logicky ekvivalentní:

SELECT *
FROM a
INNER JOIN b
    ON a.id = b.id
    AND a.something = something
    AND b.something = something

a obecně budou mít stejný plán provádění.

Na druhou stranu:

SELECT *
FROM a
LEFT JOIN b
    ON a.id = b.id
WHERE a.something = something
    AND b.something = something

NENÍ ekvivalentní:

SELECT *
FROM a
LEFT JOIN b
    ON a.id = b.id
    AND a.something = something
    AND b.something = something

a tak je optimalizátor nepřevede na stejný plán provádění.

Optimalizátor je velmi chytrý a dokáže poměrně úspěšně přesouvat věci, včetně sbalování pohledů a funkcí s inline tabulkou, stejně jako poměrně úspěšně posouvat věci dolů prostřednictvím určitých druhů agregátů.

Typicky, když píšete SQL, musí být srozumitelný, udržovatelný a správný. Pokud jde o efektivitu provádění, pokud má optimalizátor potíže s přeměnou deklarativního SQL na plán provádění s přijatelným výkonem, lze kód někdy zjednodušit nebo přidat vhodné indexy či rady nebo je rozdělit na kroky, které by měly provádět rychleji – to vše v po sobě jdoucích řádech invazivity.



  1. Stránkování pomocí OFFSET / FETCH:Lepší způsob

  2. Nelegální mix porovnávání Chyba MySQL

  3. Jak předat parametr sql do IN()?

  4. Instalace MariaDB 10.1 v Debian Jessie a spouštění různých dotazů MariaDB