Die Annahmen, die dem Entwurf von SQL Anywhere zugrunde liegen, erfordern, dass mit Speicher sparsam umgegangen wird und standardmäßig die ersten Ergebnisse von einem Cursor so schnell wie möglich zurückgeliefert werden. Mit diesem Ziel schreibt SQL Anywhere alle SET-Operationen mit Unterabfrage, wie IN-, ANY- oder SOME-Prädikate, in EXISTS- oder NOT EXITS-Prädikate um, wenn eine solche Neuschreibung semantisch korrekt ist. Dadurch vermeidet SQL Anywhere das Erstellen unnötiger Arbeitstabellen und ermittelt so möglicherweise leichter einen geeigneten Index, durch den er auf die Tabelle zugreifen kann.
Nicht korrelierte Unterabfragen sind Unterabfragen, die keine explizite Referenz auf Tabellen aufweisen, die in den verbleibenden Teilen höherer Ebenen der Abfrage enthalten sind.
Es folgt eine gewöhnliche Abfrage, die eine nicht korrelierte Unterabfrage enthält. Sie wählt Informationen über alle Kunden aus, die am 01. Januar 2001 keine Bestellung aufgegeben haben.
SELECT * FROM Customers c WHERE c.ID NOT IN ( SELECT o.CustomerID FROM SalesOrders o WHERE o.OrderDate = '2001-01-01' ); |
Eine Möglichkeit zur Auswertung dieser Abfrage wäre es, eine Arbeitstabelle aller Kunden in der Tabelle "SalesOrders" zu erstellen, die am 1. Januar 2001 bestellt haben, um dann die Tabelle "Customers" zu lesen und eine Zeile für jeden Kunden zu extrahieren, der in der Arbeitstabelle aufgelistet ist.
SQL Anywhere vermeidet allerdings ein Materialisieren von Ergebnissen in der Form von Arbeitstabellen. Er bevorzugt Pläne, die die ersten Zeilen eines Ergebnisses am schnellsten zurückgeben. Daher schreibt der Optimierer solche Abfragen unter Verwendung des NOT EXISTS-Prädikats um. In dieser Form wird die Unterabfrage korreliert: Die Unterabfrage enthält nun eine explizite Außenreferenz auf die ID-Spalte der Customer-Tabelle.
SELECT * FROM Customers c WHERE NOT EXISTS ( SELECT * FROM SalesOrders o WHERE o.OrderDate = '2000-01-01' AND o.CustomerID = c.ID ); |
Diese Abfrage ist mit der vorherigen Abfrage semantisch gleichwertig, aber in diesem Format werden mehrere Vorteile offensichtlich:
Der Optimierer kann wählen, ob er den Index des Attributs CustomerID oder des Attributs OrderDate der Tabelle SalesOrders benutzt. In der SQL Anywhere-Beispieldatenbank haben allerdings nur die ID- und die CustomerID-Spalten einen Index.
Der Optimierer hat die Wahl, die Unterabfrage aufzulösen, ohne Zwischenergebnisse in Form von Arbeitstabellen zu materialisieren.
Der Datenbankserver kann die Ergebnisse einer korrelierten Unterabfrage während der Ausführung in einen Cache legen. Dies ermöglicht die Wiederverwendung von zuvor berechneten Werten dieses Prädikats für dieselben Werte der Außenreferenz "c.ID". Im Fall der obigen Abfrage ist die Ablage im Cache nicht hilfreich, da die Kundennummern in der Kundentabelle eindeutig sind. Daher wird die Unterabfrage immer mit unterschiedlichen Werten für die Außenreferenz "c.ID" berechnet.
Weitere Hinweise zur Cachebenutzung bei Unterabfragen finden Sie unter Cachebenutzung von Unterabfragen und Funktionen.
Kommentieren Sie diese Seite in DocCommentXchange. Senden Sie uns Feedback über diese Seite via E-Mail. |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |