Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » SQL Anywhere Server - SQL-Benutzerhandbuch » Abfrageverarbeitung » Abfragen optimieren und ausführen » Semantische Abfragentransformation

 

Unterabfragen entschachteln

Sie können mit der benutzerfreundlichen Syntax der SQL-Sprache Anweisungen als verschachtelte Abfragen ausdrücken. Das Umschreiben von verschachtelten Abfragen in Joins führt häufig zu einer effizienteren Ausführung und wirksameren Optimierung, da SQL Anywhere die sehr selektiven Bedingungen in der WHERE-Klausel einer Unterabfrage nutzen kann. Allgemein werden korrelierte Unterabfragen mit nicht mehr als einer Tabelle in der FROM-Klausel, die in den Prädikaten ANY, ALL und EXISTS benutzt werden, immer entschachtelt. Eine nicht korrelierte Unterabfrage oder eine Unterabfrage mit mehr als einer Tabelle in der FROM-Klausel wird entschachtelt, wenn aufgrund der Abfragesemantik erkennbar ist, dass die Unterabfrage nicht mehr als eine Zeile liefert.

Beispiele

Die Unterabfrage im folgenden Beispiel kann höchstens eine Zeile für jede Zeile im Außenblock in Übereinstimmung bringen. Weil hier immer nur eine Zeile gefunden wird, erkennt SQL Anywhere, dass er dies in einen Inner-Join konvertieren kann.

SELECT s.*
FROM SalesOrderItems s
WHERE EXISTS
    ( SELECT *
      FROM Products p
      WHERE s.ProductID = p.ID
         AND p.ID = 300 AND p.Quantity > 20);

Nach der Konvertierung wird diese Anweisung intern unter Verwendung der Join-Syntax ausgedrückt.

SELECT s.*
FROM Products p JOIN SalesOrderItems s
   ON p.ID = s.ProductID
WHERE p.ID = 300 AND p.Quantity > 20;

p<Products> JNL s<FK_ProductID_ID>

Auf ähnliche Weise enthält die folgende Abfrage ein konjunktives EXISTS-Prädikat in einer Unterabfrage. Diese Unterabfrage kann mehr als einer Zeile entsprechen.

SELECT p.*
FROM Products p
WHERE EXISTS
    ( SELECT *
      FROM SalesOrderItems s
      WHERE s.ProductID = p.ID
         AND s.ID = 2001);

SQL Anywhere konvertiert diese Abfrage in einen Inner-Join mit DISTINCT in der SELECT-Liste.

SELECT DISTINCT p.*
FROM Products p JOIN SalesOrderItems s
   ON p.ID = s.ProductID
WHERE s.ID = 2001;

Work[ DistH[ s<FK_ID_ID> JNL p<Products> ] ]

SQL Anywhere kann auch Unterabfragen in Vergleichen eliminieren, wenn die Unterabfrage mit höchstens einer Zeile für jede Zeile im Außenblock übereinstimmt. Dies ist bei der folgenden Abfrage der Fall.

SELECT *
FROM Products p
WHERE p.ID =
    ( SELECT s.ProductID
      FROM SalesOrderItems s
      WHERE s.ID = 2001
         AND s.LineID = 1 );

SQL Anywhere schreibt die Abfrage folgendermaßen um:

SELECT p.*
FROM Products p, SalesOrderItems s
WHERE p.ID = s.ProductID
   AND s.ID = 2001
   AND s.LineID = 1;

s<SalesOrderItems> JNL p<Products>

Die Durchgangstabelle DUMMY wird als spezielle Tabelle behandelt, wenn Neuschreibungsoptimierungen ausgeführt werden, um die Unterabfrage zu entschachteln. Eine Entschachtelung von Unterabfragen findet bei Unterabfragen des Formats SELECT Ausdruck FROM DUMMY immer statt, selbst wenn die Unterabfrage nicht korreliert ist.