Was ist besser in IN ()? Unterabfrage oder Werteliste

7

Wenn Sie Zeilen suchen oder aktualisieren und die where-Anweisung IN () verwenden, ist es besser, Werte mit Unterabfrage auszuwählen oder Werte zu definieren, oder gibt es keinen Effizienzunterschied zwischen diesen? Zum Beispiel:

SELECT a FROM b WHERE c IN( SELECT c FROM x )

ODER

SELECT a FROM b WHERE c IN(1,2,3,4,5,6,...hundreds values...)
stix
quelle

Antworten:

6

Wenn Sie die Werte in einer Tabelle haben und die Spalte indiziert ist , würde ich erwarten, dass sie effizienter ist als die Verwendung einer Werteliste. Beachten Sie, dass es dafür mehrere Möglichkeiten gibt - insbesondere, weil diese Art von Abfragen ( WHERE c IN (SELECT c FROM x)) in einigen, nicht so alten MySQL-Versionen nicht vollständig optimiert ist:

SELECT a FROM b WHERE c IN ( SELECT c FROM x ) ;

Sie können (wenn x (c)keine NULLWerte vorhanden sind) wie folgt umschreiben :

SELECT a FROM b WHERE EXISTS ( SELECT 1 FROM x WHERE x.c = b.c ) ;

oder (wenn x (c)eindeutige Werte vorliegen) als:

SELECT b.a FROM b JOIN x ON x.c = b.c ;

Jetzt müssen Sie 4 Versionen testen. Das tatsächliche Verhalten hängt natürlich von mehreren weiteren Faktoren ab (neben Abfrage, Indizierung, Versionen) wie Tabellengrößen, Werteverteilungen, MySQL-Einstellungen, verfügbarem Speicher, anderen laufenden Abfragen, Mondphase, Festplatteneffizienz usw.

Alles in allem ist es am besten, in Ihrer Umgebung alle verfügbaren Optionen zu testen und auszuwählen, was für Sie am besten funktioniert.

ypercubeᵀᴹ
quelle
Vielen Dank für die Idee mit EXISTS, in meiner Umgebung ist es 5x schneller :)
Stix
@stix Wenn Sie Erfahrung sammeln, werden Sie wahrscheinlich feststellen, dass die Option EXISTS für bestimmte Abfragen gut funktioniert. Ich finde, es funktioniert am besten, wenn die Ergebnismenge ohne die zusätzliche Tabelle kleiner ist als die Anzahl der Einträge, die in der zusätzlichen Tabelle übereinstimmen. In anderen Fällen ist es möglicherweise langsamer als eine der bereitgestellten Optionen.
BillThor
@ BillThor guter Punkt, danke für die Information
Stix