2016-12-01 7 views
0

は、私はそれが唯一のトランザクションごとに一度実行する必要があるので、長時間実行クエリの結果をキャッシュするPostgresの関数を作成していますよ私のクエリのすべてを実行し、この機能に参加:インデックスの結果

SELECT mt.* 
FROM my_table1 mt 
    INNER JOIN get_records('new') nr ON mt.id = nr.id 
SELECT mt.* 
FROM my_table2 mt 
    INNER JOIN get_records('new') nr ON mt.id = nr.id 
SELECT mt.* 
FROM my_table3 mt 
    INNER JOIN get_records('new') nr ON mt.id = nr.id 
-- ... many more 

私は、これらのうちのどれが最初に実行されるか、またはどのような順序で実行されるかを保証せずに、これらの全体を積み重ねました。

これは、一時テーブルの主キーインデックスが使用されていないことを除いて、正常に機能します。

クエリの結果だけでなく、Postgres関数から「テーブル」を返すにはどうすればよいですか?

  1. 私は、一時テーブルの代わりに、「where clause doesn't get pushed into view that contains aggregation」問題を回避するマテリアライズド・ビューを構築する機能を使用しています。
  2. 私はテンポラリテーブルを作成してから、すべてのクエリで直接参照することができますが、クエリを早期に実行するために何らかのブロックメカニズムを組み込む必要があります。そのようなメカニズムを非常にうまくサポートしていません。
+1

一時テーブルを作成しないでください。一時テーブルは使用しないでください。一時テーブルを分析しないでください。 "very_complex_nested_query"を普通の 'sql'関数に入れてください。 'sql'関数を使ったクエリは、PL/pgSQLがオプティマイザに提供するブラックボックスよりはるかに良く最適化できます。 –

+0

@a_horse_with_no_nameしかし、 "very_complex_nested_query"は実行に5分かかっており、結果を何百もの別々のクエリに結合しているので、合計実行時間に日数を追加します。これは、テンポラリテーブルの正確な使用例ではありませんか? 「プレーンSQL関数」とはどういう意味ですか? –

+0

'language plpgsql'の代わりに' language sq'を意味しますが、それをインデックス化したい場合は、tempテーブルにインデックスを作成する必要があります。 –

答えて

0

あなたは

STABLE関数はデータベースを変更することができないことを示し、単一のテーブルの中にスキャンすることを、それは一貫して同じ引数の値に対して同じ結果を返すことを示し修飾子STABLEを試すことができますその結果はSQL文全体で変更される可能性があります。

newer Postgresのバージョンもマテリアライズドビューをサポートしています。結合のマテリアライズド・ビューを作成できます。 AFAIKのマテリアライズドビューはインデックスもサポートしています。

+0

FROM句で使用されているテーブルを返すことで、一度だけスキャンされませんか?どちらの場合も、STABLEでもIMMUTABLEでもtempテーブルの基礎となるインデックスが公開されていないようです。マテリアライズド・ビューでは、集計を実行するとチェック制約(パーティション表など)を利用できないため、すべてのパーティションがスキャンされます(5分間の問合せは18 -hour query) - これは、私が1万行のクエリプランを見たときに私にとっては非常に驚きでした! –

関連する問題