0

Greenplum PostgreSQLに、Oracleで以下のようにオプティマイザーのヒントが行うようWITH句でサブクエリを具体化するように強制する方法はありますか?MATERIALIZEINLINE

WITH dept_count AS (
  SELECT /*+ MATERIALIZE */ deptno, COUNT(*) AS dept_count
  FROM   emp
  GROUP BY deptno)
SELECT ...

私はこれをしばらく探していましたが、Oracleでこの機能を見つけるだけでした。

を使用できることはわかっていますがCREATE TABLE AS、同様のクエリがいくつかあるため、クエリごとに一時テーブルを削除する必要があります。これは非常に不便で、非効率的である可能性があります。

更新:次の表をテストしました:

CREATE TABLE test (id: INT);

EXPLAIN WITH test2 AS (SELECT id FROM test)
SELECT COUNT(*) FROM test2;

                                 QUERY PLAN                                     
------------------------------------------------------------------------------------
Aggregate  (cost=0.36..0.37 rows=1 width=8)
   ->  Gather Motion 32:1  (slice1; segments: 32)  (cost=0.01..0.35 rows=1 width=8)
         ->  Aggregate  (cost=0.01..0.01 rows=1 width=8)
               ->  Subquery Scan test2  (cost=0.00..0.00 rows=1 width=0)
                     ->  Seq Scan on test  (cost=0.00..0.00 rows=1 width=4)

GreenplumPostgresql8.2を使用しています

4

2 に答える 2

1

一時テーブル

セッションの間存続する一時テーブルを探している場合は、実際のTEMPORARY TABLE.

CREATE TEMPORARY TABLE t AS
SELECT deptno, COUNT(*) AS dept_count
FROM   emp
GROUP  BY deptno;

SELECT ...
FROM t ...

CREATE [TEMPORARY] TABLE ASマニュアルで。

ただし、PostgreSQL には「グローバルな」一時テーブルはありません。一時テーブルは、それを作成したユーザーにのみ表示され、それが作成されたセッションの間のみ表示されます。

CTEは、それらが含まれるクエリでのみ表示されます。それを超えることはありません。

単一クエリ専用の一時テーブル

一時テーブルの可視性を 1 つのクエリに制限するには、それらをトランザクションに入れて を追加しますON COMMIT DROP。これにより、トランザクションの最後に一時テーブルが自動的に削除されます。

BEGIN;
CREATE TEMP TABLE t ON COMMIT DROP AS
SELECT ...

私が考えることができる唯一のユースケースは、これが理にかなっています:巨大な一時テーブルにインデックスを作成したい場合:

CREATE INDEX ON t(col1);

SELECT ..
FROM t ...;

ROLLBACK;

または(ここでは違いはありません):

COMMIT;

を使用する場合は、とにかくすべてがロールバックされるためROLLBACK、一時テーブルを使用せずに使用することもできます。ON COMMIT DROP

于 2013-03-09T01:48:16.900 に答える