Na tuto otázku není příliš snadné odpovědět. Měli byste vědět jednu důležitou věc:MySQL zachází s IN (<static values list>)
a IN (<subquery>)
jako různé dotazy
. První se rovná porovnání rozsahu (jako .. OR = .. OR =
), zatímco sekunda se rovná = ANY ()
- a není to totéž. Stručně řečeno:pomocí IN
with subquery způsobí dotaz s ANY()
a MySQL k tomu nepoužije index, i když je poddotaz nezávislý a vrací statický seznam hodnot . Smutné ale pravdivé. MySQL to nedokáže předvídat, a tak index nebude použit, i když je to zřejmé. Pokud použijete JOIN
(tj. přepište svůj IN (<subquery>)
) - pak MySQL použije index pro JOIN
stavu, pokud je to možné.
Nyní, druhý případ může být o JOIN
a IN
při použití oddílů. Pokud použijete JOIN
- pak, bohužel - ale MySQL také není schopno předvídat oddíly pro JOIN
v běžném případě - a použije k tomu celou sadu oddílů. Nahrazení JOIN
na IN (<static list>)
změní EXPLAIN PARTITION
obrázek:MySQL použije pouze ty oddíly, které jsou potřeba pro výběr hodnot z rozsahu, specifikovaného v IN
doložka. Ale opět to nebude fungovat s IN (<subquery>)
.
Závěrem – je smutné, když mluvíme o tom, jak MySQL zachází s IN
poddotazy - a v běžném případě jej nelze nahradit JOIN
bezpečně (jedná se o případ rozdělení). Běžné řešení tedy bude:oddělit poddotaz od hlavního dotazu na úrovni aplikace . Pokud mluvíme o nezávislém dílčím dotazu, vracení seznamu statických hodnot, je to nejlepší návrh – pak můžete tento seznam hodnot nahradit jako IN(<static list>)
a získejte výhody:MySQL pro to bude používat index, a pokud mluvíme o oddílech, budou použity pouze skutečně potřebné.