PostgreSQL共通テーブル式と一時テーブル?


11

WITH上のPostgreSQLのドキュメントは、次の例を示します。

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;

それはまた注意します:

WITHクエリの便利なプロパティは、親クエリまたは兄弟WITHクエリによって複数回参照されている場合でも、親クエリの実行ごとに1回だけ評価されることです。

WITH再帰的な評価など、他にも使用できると思います。しかし、上記の例では、WITH一時テーブルの使用と作成の間に重要な違いはありますか?


CTEを使用してクエリを構築する場合、別の列を追加するSELECTWITHは、名前を入力して再実行するだけです。一時テーブルとの間にそれがかかるだろうDROPCREATE。一方、クエリを作成し、静的データを何度も再利用する場合は、インデックスを使用して一時テーブルを作成すると、CTEに対して確実にメリットがあります。
Vao Tsun 2016年

@VaoTsun クエリ内で使用TEMPORARY TABLEする場合ON COMMIT DROPは、クエリを変更して再実行するだけでも問題ありませんか?postgresql.org/docs/9.6/static/sql-createtable.html
Nathan Long

回答:


16

微妙な違いがいくつかありますが、劇的なものはありません。

  • 一時テーブルにインデックスを追加できます。
  • 一時テーブルはセッションの存続期間(またはON COMMIT DROPトランザクションの場合)存在しますが、wheras WITHは常にクエリに厳密にスコープされます。
  • クエリが関数/プロシージャを呼び出す場合、一時テーブル表示できWITHますが、テーブル式表示できません
  • 一時テーブルVACUUMは、システムカタログでWITH動作しない作業を生成します。それを作成/埋めるために追加の往復が必要であり、サーバーのキャッシュ管理で追加の作業が必要になるため、効率が少し低下します。

全体として、WITHインデックスを作成することのメリットがわかっている場合を除き、一時テーブルを使用することをお勧めします。

ただし、他のオプションであるFROM節のサブクエリには、非常に異なる利点があります。特にインライン化でき、修飾子をプルアップ/プッシュダウンできます。私は最近のブログ記事でこれについて書きまし


ビューと一時ビューはどうですか?
CMCDragonkai 2016年

1
少しの間ですが、CTE用語より一時テーブルに近いです。インデックスはありません。セッションスコープ。関数/手順に表示されます。カタログ掃除機が必要です。
クレイグリンガー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.