In Inline-Ansichten können Sie aus einer Unterabfrage auswählen, als wäre es eine andere Tabelle:
SELECT
*
FROM /* Selecting from a query instead of table */
(
SELECT
c1
FROM
t1
WHERE
c1 > 0
) a
WHERE
a.c1 < 50;
Ich habe gesehen, dass dies mit verschiedenen Begriffen bezeichnet wurde: Inline-Ansichten, WITH-Klausel, CTE und abgeleitete Tabellen. Mir scheint, dass es sich um unterschiedliche herstellerspezifische Syntax für dieselbe Sache handelt.
Ist das eine falsche Annahme? Gibt es technische / Leistungsunterschiede zwischen diesen?
oracle
cte
derived-tables
Kshitiz Sharma
quelle
quelle
WITH...
). Sie können jede abgeleitete Tabelle als CTE umschreiben, aber möglicherweise nicht umgekehrt (z. B. rekursiver CTE oder mehrfache Verwendung des CTE)Antworten:
Es gibt einige wichtige Unterschiede zwischen Inline-Ansichten (abgeleitete Tabellen) und WITH-Klausel (CTE) in Oracle. Einige von ihnen sind ziemlich universell, dh sie sind auf andere RDBMS anwendbar.
WITH
kann verwendet werden, um rekursive Unterabfragen zu erstellen, Inline-Ansicht -not (soweit ich weiß, gilt das gleiche für alle RDBMS, die CTE unterstützen)WITH
Klausel wird eher zuerst physisch ausgeführt. In vielen FällenWITH
kann der Optimierer durch Auswahl zwischen und Inline-Ansicht unterschiedliche Ausführungspläne auswählen (ich denke, es ist herstellerspezifisch, möglicherweise sogar versionenspezifisch).WITH
können als temporäre Tabelle ausgeführt werden (mir ist nicht bekannt, ob ein anderer Anbieter als Oracle diese Funktion unterstützt).WITH
können mehrfach, in anderen Unterabfragen und in der Hauptabfrage referenziert werden (wahr für die meisten RDBMS).quelle
LATERAL
sei denn, sie wird verwendet.Andere Antworten decken die Syntaxunterschiede ziemlich gut ab, daher werde ich nicht darauf eingehen. Stattdessen bezieht sich diese Antwort nur auf die Leistung in Oracle.
Das Oracle-Optimierungsprogramm kann die Ergebnisse eines CTE in einer internen temporären Tabelle materialisieren. Hierzu wird eine Heuristik anstelle einer kostenbasierten Optimierung verwendet. Die Heuristik lautet etwa "Materialisieren Sie den CTE, wenn es sich nicht um einen trivialen Ausdruck handelt und der CTE in der Abfrage mehrmals referenziert wird". Es gibt einige Abfragen, bei denen die Materialisierung die Leistung verbessert. Es gibt einige Abfragen, bei denen die Materialisierung die Leistung dramatisch beeinträchtigt. Das folgende Beispiel ist etwas erfunden, aber es veranschaulicht den Punkt gut:
Erstellen Sie zunächst eine Tabelle mit einem Primärschlüssel, der Ganzzahlen von 1 bis 10000 enthält:
Betrachten Sie die folgende Abfrage, die zwei abgeleitete Tabellen verwendet:
Wir können uns diese Abfrage ansehen und schnell feststellen, dass keine Zeilen zurückgegeben werden. Oracle sollte in der Lage sein, den Index auch dazu zu verwenden. Auf meinem Computer wird die Abfrage fast sofort mit dem folgenden Plan beendet:
Ich wiederhole mich nicht gern, also versuchen wir die gleiche Abfrage mit einem CTE:
Hier ist der Plan:
Das ist ein wirklich schlechter Plan. Anstatt den Index zu verwenden, materialisiert Oracle 10000 x 10000 = 100000000 Zeilen in einer temporären Tabelle, um schließlich 0 Zeilen zurückzugeben. Die Kosten für diesen Plan liegen bei 6 Mio., was viel höher ist als bei der anderen Abfrage. Die Abfrage dauerte auf meinem Computer 68 Sekunden.
Beachten Sie, dass die Abfrage möglicherweise fehlgeschlagen ist, wenn im temporären Tabellenbereich nicht genügend Speicher oder freier Speicherplatz vorhanden ist.
Ich kann den undokumentierten
INLINE
Hinweis verwenden, um zu verhindern, dass der Optimierer den CTE materialisiert:Diese Abfrage kann den Index verwenden und wird fast sofort beendet. Die Kosten für die Abfrage sind die gleichen wie zuvor. 11. Für die zweite Abfrage führte die von Oracle verwendete Heuristik dazu, dass eine Abfrage mit geschätzten Kosten von 6 Mio. anstelle einer Abfrage mit geschätzten Kosten von 11 ausgewählt wurde.
quelle
Gibt für SQL Server
WITH CTE
die temporär benannte Ergebnismenge an, ist jedoch nur für die erste erforderlichCTE
. dhDies ist jedoch keine Unterabfrage oder korrelierte Unterabfrage. Es gibt Dinge, die Sie mit einem CTE tun können, was Sie mit einer Unterabfrage in SQL Server nicht tun können, z. B. das Aktualisieren der Tabellen, auf die in einem CTE verwiesen wird. Hier ist ein Beispiel für die Aktualisierung einer Tabelle mit einem CTE.
Eine Unterabfrage wäre so etwas wie
Oder eine korrelierte Unterabfrage ist das, was Sie in Ihrem OP angegeben haben, wenn Sie Ihre Ergebnisse basierend auf a.c1 referenzieren / verbinden / einschränken möchten.
Sie sind also definitiv nicht dasselbe, obwohl Sie in vielen Fällen eine oder mehrere dieser Methoden verwenden können, um das gleiche Ergebnis zu erzielen. Es kommt nur darauf an, was das Endergebnis ist.
quelle
Der Hauptunterschied zwischen
with
Klausel und einer Unterabfrage in Oracle besteht darin, dass Sie eine Abfrage innerhalb der Klausel mehrmals referenzieren können. Sie können dann einige Optimierungen damit vornehmen, zmaterialize
. B. mithilfe eines Hinweises eine temporäre Tabelle erstellen. Sie können damit auch rekursive Abfragen durchführen, indem Sie innerhalb einerwith
Klausel auf sich selbst verweisen . Mit einer Inline-Ansicht ist das nicht möglich.Weitere Informationen finden Sie hier und hier .
quelle
MATERIALIZE
bzw. einem Hinweis überschreiben .INLINE
für das Gegenteil.materialize
Hinweises eine gültige Option. Ich musste es manchmal angeben, wenn ich sehr komplexe Abfragen optimierte, bei denen ich wusste, dass die Materialisierung des CTE dem Ausführungsplan zugute kommen würde.Sie müssen mit CTEs in SQL Server vorsichtig sein, nicht nur mit Oracle. Es gibt Fälle, in denen Abfragen bei der Verwendung von CTEs im Vergleich zu Unterabfragen, Cross Apply usw. viel schlechter abschneiden.
Wie immer ist es wichtig, jede Abfrage unter verschiedenen Lastbedingungen zu testen, um festzustellen, welche am besten funktioniert.
Ähnlich wie bei @scsimon mit Oracle macht MS SQL Server manchmal nicht das, was Sie in Bezug auf die Indexnutzung erwarten.
Wenn Sie dieselben Daten mehrmals verwenden, können CTEs nützlicher sein. Wenn Sie sie nur einmal verwenden, ist eine Unterabfrage in großen Datenmengen häufig schneller.
zB wählen Sie * aus (meine Unterabfrage) verbinden Sie etwas anderes ...
quelle