sql >> Databáze >  >> RDS >> Mysql

Výkon SQL UNION vs. OR

Buď článek, který jste četli, použil špatný příklad, nebo jste jeho pointu špatně interpretovali.

select username from users where company = 'bbc' or company = 'itv';

To je ekvivalentní:

select username from users where company IN ('bbc', 'itv');

MySQL může používat index na company pro tento dotaz v pohodě. Není třeba dělat žádnou UNION.

Ošemetnější případ je, kdy máte OR stav, který zahrnuje dva různé sloupce.

select username from users where company = 'bbc' or city = 'London';

Předpokládejme, že existuje index company a samostatný index na city . Vzhledem k tomu, že MySQL obvykle používá pouze jeden index na tabulku v daném dotazu, který index by měl použít? Pokud používá index na company , stále bude muset provést skenování tabulky, aby nalezlo řádky s city je Londýn. Pokud používá index na city , musel by prohledat řádky, kde je company je bbc.

UNION řešení je pro tento typ případu.

select username from users where company = 'bbc' 
union
select username from users where city = 'London';

Nyní může každý dílčí dotaz používat index pro své vyhledávání a výsledky dílčího dotazu jsou kombinovány pomocí UNION .

Anonymní uživatel navrhl úpravu mé odpovědi výše, ale moderátor úpravu odmítl. Měl to být komentář, ne úprava. Tvrzení navrhované úpravy bylo, že UNION musí třídit sadu výsledků, aby se odstranily duplicitní řádky. To zpomalí běh dotazu a optimalizace indexu je proto špinavá.

Moje odpověď je, že indexy pomáhají snížit sadu výsledků na malý počet řádků, než dojde k UNION. UNION ve skutečnosti odstraňuje duplikáty, ale k tomu musí seřadit pouze malou sadu výsledků. Mohou nastat případy, kdy se klauzule WHERE shodují s významnou částí tabulky a řazení během UNION je stejně nákladné jako pouhé skenování tabulky. Je však běžnější, že se sada výsledků sníží o indexovaná vyhledávání, takže třídění je mnohem méně nákladné než skenování tabulky.

Rozdíl závisí na datech v tabulce a hledaných výrazech. Jediný způsob, jak určit nejlepší řešení pro daný dotaz, je vyzkoušet obě metody v profiler dotazů MySQL a porovnat jejich výkon.



  1. Použití DBCC CLONEDATABASE a Query Store pro testování

  2. postgres - kde v (seznam) - sloupec neexistuje

  3. Jak vyřešit ORA-011033:Probíhá inicializace nebo vypínání serveru ORACLE

  4. Jak mohu VYBRAT více sloupců v CASE WHEN na SQL Server?