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.