Не е толкова лесно да се отговори на този въпрос. Трябва да знаете едно важно нещо:MySQL третира IN (<static values list>)
и IN (<subquery>)
като различни заявки
. Първият е равен на сравнение на диапазони (като .. OR = .. OR =
), докато секундата е равна на = ANY ()
- и не е същото. Така че, казано накратко:използвайки IN
с подзаявка ще предизвика заявка с ANY()
и MySQL няма да използва индекс за това, дори ако подзаявката е независима и връща статичен списък със стойности . Тъжно, но истина. MySQL не може да предвиди това и така индексът няма да се използва, дори ако е очевидно. Ако ще използвате JOIN
(т.е. пренапишете своя IN (<subquery>)
) - тогава MySQL ще използва индекс за JOIN
условие, ако е възможно.
Сега, вторият случай може да е за JOIN
и IN
при използване на дялове. Ако ще използвате JOIN
- тогава, за съжаление - но MySQL също не е в състояние да предвиди дялове за JOIN
в общия случай - и ще използва целия набор от дялове за него. Замяна на JOIN
до IN (<static list>)
ще промени EXPLAIN PARTITION
картина:MySQL ще използва само онези дялове, които са необходими за избор на стойности от диапазон, посочени в IN
клауза. Но, отново, това няма да работи с IN (<subquery>)
.
Като заключение - тъжно е, когато говорим за това как MySQL се справя с IN
подзаявки - и в общия случай не може да бъде заменен с JOIN
безопасно (това е за случая на разделяне). И така, общото решение ще бъде:отделете подзаявката от основната заявка на ниво приложение . Ако говорим за независима подзаявка, връщаща списък със статични стойности, това е най-доброто предложение - тогава можете да замените този списък със стойности като IN(<static list>)
и да спечелите предимства:MySQL ще използва индекс за него и, ако говорим за дялове, ще се използва само действително необходими от тях.