Verwenden von Union anstelle von OR

Manchmal können langsame Abfragen durch geringfügiges Ändern der Abfrage behoben werden. Ein solches Beispiel kann veranschaulicht werden, wenn mehrere Werte in einer WHERE-Klausel mit dem Operator OR oder IN verglichen werden. Oft kann ein ODER einen Index- oder Tabellenscan verursachen, was hinsichtlich des E / A-Verbrauchs oder der Gesamtabfragegeschwindigkeit möglicherweise nicht der bevorzugte Ausführungsplan ist.

Viele Variablen kommen ins Spiel, wenn der Abfrageoptimierer einen Ausführungsplan erstellt. Diese Variablen umfassen viele Hardwareeigenschaften, Instanzeinstellungen, Datenbankeinstellungen, Statistiken (Tabelle, Index, automatisch generiert) sowie eine Möglichkeit zum Schreiben einer Abfrage. Hier ändern wir die Art und Weise, wie wir die Anfrage schreiben. Unabhängig davon, wie unerwartet dies erscheinen mag, kann der Pfad, dem sie folgen, je nach Format der Abfrage völlig unterschiedlich sein, selbst wenn zwei verschiedene Abfragen dieselben Ergebnisse zurückgeben können.

UNION vs OR


Für die meisten meiner Erfahrungen mit SQL Server ist OR normalerweise weniger effizient als UNION. Was normalerweise mit OR passiert, ist, dass es oft einen Scan verursacht. Dies mag in einigen Fällen manchmal der beste Weg sein, und ich werde es als separaten Artikel belassen, aber im Allgemeinen habe ich festgestellt, dass dies der Hauptgrund für die Langsamkeit ist, wenn eine große Anzahl von Einträgen betroffen ist. Beginnen wir also mit unserem Vergleich.

Hier ist unsere ODER-Anweisung:

SELECT SalesOrderID, * FROM sales.SalesOrderDetail WHERE ProductID = 750 OR ProductID = 953 



Aus diesem Ausführungsplan geht hervor, dass wir 121.000 Zeilen scannen. (Sie können die Anzahl der Zeilen nicht sehen, aber es ist).

Jetzt führen wir dieselbe Abfrage aus, die jedoch mit UNION anstelle von OR geschrieben wurde:

 SELECT [SalesOrderID], * FROM sales.SalesOrderDetail WHERE ProductID = 750 UNION SELECT [SalesOrderID], * FROM sales.SalesOrderDetail WHERE ProductID = 953 



Hier sehen wir zwei Geschäftsbereiche. Ein Zweig betrifft 358 Zeilen und die anderen 346 Zeilen. Es wurde festgestellt, dass beide Zweige eine Verkettungsoperation ausführen, die beide Ergebnissätze kombiniert. Wir haben zwei separate Suchvorgänge, aber wir haben auch eine Schlüsselsuche, um die erforderliche SELECT-Liste zu erhalten. Dies war für den Scanvorgang nicht erforderlich, da immer noch alle Zeilen im Scanvorgang betroffen waren, sodass die Daten während des Scanvorgangs und nicht danach abgerufen wurden. Dies liegt am Index und den Zeilen, die wir benötigen, nicht an UNION oder OR. Ich werde jedoch sagen, dass die Auswahl auch ein Faktor bei der Auswahl einer Suche oder eines Scans ist, aber wir werden dies in diesem Artikel ignorieren.

Erklärung


Warum UNION mehr Suchen anstelle von Scans verursacht, weil jede Operation eine bestimmte Selektivitätsanforderung erfüllen muss, um sich für eine Suche zu qualifizieren. (Selektivität ist die Eindeutigkeit einer bestimmten gefilterten Spalte). ODER tritt in einer einzelnen Operation auf. Wenn also die Selektivität für jede Spalte kombiniert wird und einen bestimmten Prozentsatz überschreitet, wird das Scannen als effizienter angesehen.

Da UNION standardmäßig für jeden Operator eine separate Operation ausführt, wird die Selektivität jeder Spalte nicht kombiniert, sodass die Suche besser durchgeführt werden kann. Da UNION nun zwei Operationen ausführt, müssen sie ihre Ergebnismengen mit der oben beschriebenen Verkettungsoperation abgleichen. Dies ist normalerweise keine teure Operation.

Es ist auch zu beachten, dass die OR-Klausel genauso funktioniert wie die IN-Anweisung.

Hoffe dieser Tipp hilft. Ich glaube, dass dies sehr wertvoll ist, wenn Sie mit Systemen arbeiten, die eine hohe Parallelität erfordern.

Source: https://habr.com/ru/post/de464623/


All Articles