Ce n'est pas trop facile de répondre à cette question. Vous devez savoir une chose importante :MySQL traite IN (<static values list>)
et IN (<subquery>)
comme différentes requêtes
. Le premier est égal à comparaison de plage (comme .. OR = .. OR =
) tandis que second est égal à = ANY ()
- et ce n'est pas pareil. Donc, pour faire court :utiliser IN
avec une sous-requête provoquera une requête avec ANY()
et MySQL n'utilisera pas l'index pour cela même si la sous-requête est indépendante et renvoie une liste statique de valeurs . Triste mais vrai. MySQL ne peut pas prédire cela et donc l'index ne sera pas utilisé même si c'est évident. Si vous utilisez JOIN
(c'est-à-dire réécrivez votre IN (<subquery>)
) - alors MySQL utilisera l'index pour JOIN
condition, si c'est possible.
Maintenant, le deuxième cas peut concerner JOIN
et IN
lors de l'utilisation de partitions. Si vous utilisez JOIN
- alors, malheureusement - mais MySQL n'est pas non plus capable de prédire les partitions pour JOIN
dans le cas courant - et il utilisera un ensemble complet de partitions pour cela. Remplacer JOIN
à IN (<static list>)
changera EXPLAIN PARTITION
image :MySQL n'utilisera que les partitions nécessaires pour sélectionner les valeurs de la plage, spécifiées dans IN
clause. Mais, encore une fois, cela ne fonctionnera pas avec IN (<subquery>)
.
En conclusion - c'est triste, quand on parle de la façon dont MySQL gère IN
sous-requêtes - et dans le cas courant, il ne peut pas être remplacé par JOIN
en toute sécurité (c'est à propos du cas de partitionnement). Ainsi, la solution commune sera :séparer la sous-requête de la requête principale au niveau de l'application . Si nous parlons de sous-requête indépendante, renvoyant une liste de valeurs statiques, c'est la meilleure suggestion - alors vous pouvez remplacer cette liste de valeurs par IN(<static list>)
et gagner des avantages :MySQL utilisera l'index pour cela, et, si nous parlons de partitions, seules celles dont elles ont réellement besoin seront utilisées.