PostgreSQL Common Table Expressions gegen eine temporäre Tabelle?

11

Die PostgreSQL-Dokumentation zu WITH zeigt das folgende Beispiel:

WITH regional_sales AS (
        SELECT region, SUM(amount) AS total_sales
        FROM orders
        GROUP BY region
     ), top_regions AS (
        SELECT region
        FROM regional_sales
        WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
     )
SELECT region,
       product,
       SUM(quantity) AS product_units,
       SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;

Es stellt auch fest:

Eine nützliche Eigenschaft von WITH-Abfragen besteht darin, dass sie nur einmal pro Ausführung der übergeordneten Abfrage ausgewertet werden, selbst wenn sie von der übergeordneten Abfrage oder den Geschwister-WITH-Abfragen mehrmals referenziert werden.

Ich sehe, dass WITHdies für andere Dinge verwendet werden kann, beispielsweise für die rekursive Auswertung. Gibt es im obigen Beispiel einen wichtigen Unterschied zwischen der Verwendung WITHund der Erstellung temporärer Tabellen?

Nathan Long
quelle
wenn Sie CTE verwenden für die Abfrage aufzubauen, das Hinzufügen eines weiteren Spalte SELECTin WITHwird nur den Namen eingeben und erneut ausführen. Während mit temporären Tabelle würde es dauern DROPund CREATE. Wenn Sie dagegen eine Abfrage erstellen und statische Daten häufig wiederverwenden, ist das Erstellen einer temporären Tabelle mit Indizes definitiv vorteilhaft für CTE.
Vao Tsun
@VaoTsun Wenn Sie TEMPORARY TABLEmit ON COMMIT DROPinnerhalb einer Abfrage verwenden, müssen Sie auch nur die Abfrage ändern und erneut ausführen , oder? postgresql.org/docs/9.6/static/sql-createtable.html
Nathan Long

Antworten:

15

Es gibt ein paar subtile Unterschiede, aber nichts drastisches:

  • Sie können einer temporären Tabelle Indizes hinzufügen.
  • Temp-Tabellen sind für die ON COMMIT DROPDauer der Sitzung (oder, falls vorhanden , der Transaktion) vorhanden, wobei der Umfang WITHimmer streng auf die Abfrage beschränkt ist.
  • Wenn eine Abfrage eine Funktion / Prozedur aufruft, kann es die temporäre Tabelle sehen, aber es kann nicht alle sehen WITHTabelle Ausdrücke;
  • Eine temporäre Tabelle generiert VACUUMArbeiten an den Systemkatalogen, die WITHdies nicht tun. Sie benötigt einen zusätzlichen Roundtrip zum Erstellen / Füllen und zusätzliche Arbeit in der Cache-Verwaltung des Servers, sodass sie etwas weniger effizient ist.

Insgesamt sollten Sie WITHtemporäre Tabellen bevorzugen , es sei denn, Sie wissen, dass Sie von der Erstellung eines Index profitieren.

Die andere Option, eine Unterabfrage in der FROMKlausel, bietet jedoch ganz andere Vorteile. Es kann insbesondere inline sein und Qualifikanten können nach oben / unten gezogen werden. Ich habe darüber kürzlich in einem Blog-Artikel geschrieben .

Craig Ringer
quelle
Was ist mit Ansichten und temporären Ansichten?
CMCDragonkai
1
Ein bisschen dazwischen, aber näher an einer temporären Tabelle als an einem CTE-Begriff. Keine Indizes. Sitzungsumfang. Sichtbar für Funktionen / Prozeduren. Benötigt Katalog Vakuum.
Craig Ringer