Diese Frage ist nicht ganz einfach zu beantworten. Sie sollten eine wichtige Sache wissen:MySQL behandelt IN (<static values list>)
und IN (<subquery>)
als verschiedene Abfragen
. Der erste entspricht dem Bereichsvergleich (wie .. OR = .. OR =
), während second gleich = ANY ()
ist - und es ist nicht dasselbe. Also kurz gesagt:mit IN
mit Unterabfrage wird eine Abfrage mit ANY()
verursachen und MySQL verwendet dafür keinen Index, selbst wenn die Unterabfrage unabhängig ist und statische Werteliste zurückgibt . Traurig aber wahr. MySQL kann das nicht vorhersagen und daher wird der Index nicht verwendet, auch wenn es offensichtlich ist. Wenn Sie JOIN
verwenden (d.h. schreiben Sie Ihren IN (<subquery>)
um ) - dann verwendet MySQL den Index für JOIN
Zustand, wenn es möglich ist.
Nun könnte es im zweiten Fall um JOIN
gehen und IN
bei der Verwendung von Partitionen. Wenn Sie JOIN
verwenden - dann leider - aber MySQL ist auch nicht in der Lage, Partitionen für JOIN
vorherzusagen im allgemeinen Fall - und es wird einen ganzen Satz von Partitionen dafür verwenden. Ersetzen von JOIN
zu IN (<static list>)
ändert EXPLAIN PARTITION
Bild:MySQL verwendet nur die Partitionen, die zum Auswählen von Werten aus dem Bereich benötigt werden, der in IN
angegeben ist Klausel. Aber auch das funktioniert nicht mit IN (<subquery>)
.
Als Fazit - es ist traurig, wenn wir darüber sprechen, wie MySQL mit IN
umgeht Unterabfragen - und im Allgemeinen kann es nicht durch JOIN
ersetzt werden sicher (das ist über den Partitionierungsfall). Eine gemeinsame Lösung wird also sein:Trenne die Unterabfrage von der Hauptabfrage auf Anwendungsebene . Wenn wir von einer unabhängigen Unterabfrage sprechen, die eine statische Werteliste zurückgibt, ist das der beste Vorschlag - dann können Sie diese Werteliste durch IN(<static list>)
ersetzen und Vorteile gewinnen:MySQL wird den Index dafür verwenden, und wenn wir von Partitionen sprechen, werden nur die tatsächlich benötigten von ihnen verwendet.