Welche Leistung ist beim Umgang mit großen Datenbanken besser IN
oder OR
in der SQL- Where
Klausel?
Gibt es einen Unterschied in der Art und Weise, wie sie ausgeführt werden?
Welche Leistung ist beim Umgang mit großen Datenbanken besser IN
oder OR
in der SQL- Where
Klausel?
Gibt es einen Unterschied in der Art und Weise, wie sie ausgeführt werden?
Antworten:
Ich gehe davon aus, dass Sie den Leistungsunterschied zwischen den folgenden Elementen kennen möchten:
WHERE foo IN ('a', 'b', 'c')
WHERE foo = 'a' OR foo = 'b' OR foo = 'c'
Laut Handbuch für MySQLIN
sortiert die Liste bei konstanten Werten die Liste und verwendet dann eine binäre Suche. Ich würde mir vorstellen, dass OR
sie einzeln in keiner bestimmten Reihenfolge bewertet werden. Ist IN
also unter Umständen schneller.
Der beste Weg, dies zu wissen, besteht darin, beide in Ihrer Datenbank mit Ihren spezifischen Daten zu profilieren, um festzustellen, welche schneller sind.
Ich habe beide auf einem MySQL mit 1000000 Zeilen ausprobiert. Wenn die Spalte indiziert ist, ist kein Leistungsunterschied erkennbar - beide sind nahezu augenblicklich. Wenn die Spalte nicht indiziert ist, habe ich folgende Ergebnisse erhalten:
SELECT COUNT(*) FROM t_inner WHERE val IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);
1 row fetched in 0.0032 (1.2679 seconds)
SELECT COUNT(*) FROM t_inner WHERE val = 1000 OR val = 2000 OR val = 3000 OR val = 4000 OR val = 5000 OR val = 6000 OR val = 7000 OR val = 8000 OR val = 9000;
1 row fetched in 0.0026 (1.7385 seconds)
In diesem Fall ist die Methode mit OR etwa 30% langsamer. Das Hinzufügen weiterer Begriffe macht den Unterschied größer. Die Ergebnisse können in anderen Datenbanken und in anderen Daten variieren.
IN
Methode die Optimierung einfacher macht als eine ganze Reihe möglicherweise verwandter OR
Klauseln. Ich wäre überrascht, wenn es eine Engine gibt, bei der die OR
Methode schneller ist, aber ich bin nicht überrascht, dass es Zeiten gibt, in denen der OP langsamer ist.
OR
s durch ein ersetzen IN
?
Der beste Weg, dies herauszufinden, ist ein Blick auf den Ausführungsplan.
Ich habe es mit Oracle versucht und es war genau das gleiche.
CREATE TABLE performance_test AS ( SELECT * FROM dba_objects );
SELECT * FROM performance_test
WHERE object_name IN ('DBMS_STANDARD', 'DBMS_REGISTRY', 'DBMS_LOB' );
Obwohl die Abfrage verwendet wird IN
, wird im Ausführungsplan Folgendes verwendet OR
:
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8 | 1416 | 163 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| PERFORMANCE_TEST | 8 | 1416 | 163 (2)| 00:00:02 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_NAME"='DBMS_LOB' OR "OBJECT_NAME"='DBMS_REGISTRY' OR
"OBJECT_NAME"='DBMS_STANDARD')
INLIST ITERATOR
Operation, die es auswählen würde, wenn es einen Index gäbe, den es verwenden könnte. Dennoch , wenn ich es ausprobiert, beide IN
und OR
mit dem gleichen Ausführungsplan enden.
Der OR-Operator benötigt einen viel komplexeren Bewertungsprozess als das IN-Konstrukt, da er viele Bedingungen zulässt, die nicht nur gleich IN sind.
Hier ist ein Beispiel dafür, was Sie mit OR verwenden können, das jedoch nicht mit IN kompatibel ist: größer. größer oder gleich, kleiner, kleiner oder gleich, LIKE und einige mehr wie das Orakel REGEXP_LIKE. Beachten Sie außerdem, dass die Bedingungen möglicherweise nicht immer den gleichen Wert vergleichen.
Für das Abfrageoptimierungsprogramm ist es einfacher, den IN-Operator zu verwalten, da es sich nur um ein Konstrukt handelt, das den OR-Operator unter mehreren Bedingungen mit dem Operator = auf demselben Wert definiert. Wenn Sie den Operator OR verwenden, berücksichtigt das Optimierungsprogramm möglicherweise nicht, dass Sie den Operator = immer für denselben Wert verwenden. Wenn keine tiefere und sehr viel komplexere Ausarbeitung durchgeführt wird, kann dies wahrscheinlich ausschließen, dass nur dieser Operator vorhanden ist = Operatoren für die gleichen Werte unter allen beteiligten Bedingungen, mit dem konsequenten Ausschluss optimierter Suchmethoden wie der bereits erwähnten binären Suche.
[BEARBEITEN] Wahrscheinlich implementiert ein Optimierer möglicherweise keinen optimierten IN-Evaluierungsprozess, dies schließt jedoch nicht aus, dass dies einmal passieren könnte (mit einem Upgrade der Datenbankversion). Wenn Sie also den OR-Operator verwenden, wird die optimierte Ausarbeitung in Ihrem Fall nicht verwendet.
OR
Sinnvoll (aus Sicht der Lesbarkeit), wenn weniger Werte verglichen werden müssen.
IN
ist nützlich, insb. Wenn Sie eine dynamische Quelle haben, mit der Werte verglichen werden sollen.
Eine andere Alternative ist die Verwendung von a JOIN
mit einer temporären Tabelle.
Ich denke nicht, dass die Leistung ein Problem sein sollte, vorausgesetzt, Sie haben die erforderlichen Indizes.
Ich habe eine SQL-Abfrage in einer großen Anzahl von OR (350) durchgeführt. Postgres machen es 437.80ms .
Verwenden Sie jetzt IN:
23,18 ms