Nie jest łatwo odpowiedzieć na to pytanie. Powinieneś wiedzieć jedną ważną rzecz:MySQL traktuje IN (<static values list>)
i IN (<subquery>)
jako różne zapytania
. Pierwszy jest równy porównaniu zakresów (np. .. OR = .. OR =
) podczas gdy sekunda jest równa = ANY ()
- i to nie to samo. Krótko mówiąc:używając IN
z podzapytanie spowoduje zapytanie z ANY()
a MySQL nie użyje do tego indeksu, nawet jeśli podzapytanie jest niezależne i zwraca statyczną listę wartości . Smutne ale prawdziwe. MySQL nie może tego przewidzieć, więc indeks nie zostanie użyty, nawet jeśli jest to oczywiste. Jeśli użyjesz JOIN
(tj. przepisz swój IN (<subquery>)
) - wtedy MySQL użyje indeksu do JOIN
warunek, jeśli to możliwe.
Teraz drugi przypadek może dotyczyć JOIN
i IN
podczas korzystania z partycji. Jeśli użyjesz JOIN
- to niestety - ale MySQL również nie jest w stanie przewidzieć partycji dla JOIN
w zwykłym przypadku - i użyje do tego całego zestawu partycji. Zastępowanie JOIN
na IN (<static list>)
zmieni EXPLAIN PARTITION
obrazek:MySQL użyje tylko tych partycji, które są potrzebne do wybrania wartości z zakresu określonego w IN
klauzula. Ale znowu to nie zadziała z IN (<subquery>)
.
Podsumowując - to smutne, gdy mówimy o tym, jak MySQL obsługuje IN
podzapytania - i w powszechnym przypadku nie można ich zastąpić przez JOIN
bezpiecznie (chodzi o partycjonowanie przypadku). Dlatego powszechnym rozwiązaniem będzie:oddziel podzapytanie od głównego zapytania na poziomie aplikacji . Jeśli mówimy o niezależnym podzapytaniu, zwracającym listę wartości statycznych, to jest to najlepsza sugestia - wtedy możesz podstawić tę listę wartości jako IN(<static list>)
i zyskaj korzyści:MySQL użyje do tego indeksu, a jeśli mówimy o partycjach, zostaną użyte tylko faktycznie potrzebne z nich.