Esto no es demasiado fácil de responder a esta pregunta. Debe saber una cosa importante:MySQL trata IN (<static values list>)
y IN (<subquery>)
como diferentes consultas
. El primero es igual a comparación de rango (como .. OR = .. OR =
) mientras que el segundo es igual a = ANY ()
- y no es lo mismo. Entonces, para decirlo brevemente:usando IN
con subconsulta provocará una consulta con ANY()
y MySQL no usará el índice para eso, incluso si la subconsulta es independiente y devuelve lista estática de valores . Triste pero cierto. MySQL no puede predecir eso, por lo que el índice no se utilizará incluso si es obvio. Si usará JOIN
(es decir, reescriba su IN (<subquery>)
) - entonces MySQL usará el índice para JOIN
condición, si es posible.
Ahora, el segundo caso puede tratarse de JOIN
y IN
cuando se utilizan particiones. Si usará JOIN
- entonces, lamentablemente - pero MySQL tampoco puede predecir particiones para JOIN
en el caso común, y usará un conjunto completo de particiones para ello. Reemplazando JOIN
a IN (<static list>)
cambiará EXPLAIN PARTITION
imagen:MySQL usará solo aquellas particiones, que son necesarias para seleccionar valores del rango, especificado dentro de IN
cláusula. Pero, de nuevo, esto no funcionará con IN (<subquery>)
.
Como conclusión, es triste cuando decimos cómo MySQL está manejando IN
subconsultas - y en el caso común no se puede reemplazar con JOIN
de forma segura (eso es sobre el caso de partición). Entonces, la solución común será:separar la subconsulta de la consulta principal en el nivel de la aplicación . Si estamos hablando de una subconsulta independiente, que devuelve una lista de valores estáticos, esa es la mejor sugerencia; entonces puede sustituir esa lista de valores como IN(<static list>)
y obtenga beneficios:MySQL usará el índice para ello y, si estamos hablando de particiones, solo se usarán las que realmente se necesitan.