pl/pgsql でクエリ プランのキャッシュがどのように機能するか理解できません。
JOIN
s とs を使用してオールインワン クエリを作成したいIF
ので、複数の異なるクエリ パラメータを使用し、複数のテーブルを検索します。
最初は、pl/pgsql を使用すると、パラメーターの組み合わせごとに異なる計画が生成されると考えていましたが、そうではありません。複数のテーブルがあるためです。
PL/pgSQL 関数に直接現れる SQL コマンドは、実行のたびに同じテーブルと列を参照する必要があります。つまり、SQL コマンドでパラメーターをテーブルまたは列の名前として使用することはできません。この制限を回避するために、PL/pgSQL EXECUTE ステートメントを使用して動的コマンドを作成できますが、新しい解析分析を実行し、実行ごとに新しい実行計画を作成するという代償を払います。 ここから
毎回新しい分析を実行すると、物事が遅くなる可能性があると思います。使用しないEXECUTE
場合
ステートメントにパラメーターがない場合、または何度も実行される場合、SPI マネージャーは、特定のパラメーター値に依存しない汎用プランを作成し、それをキャッシュして再利用することを検討します。通常、これは、実行計画がその中で参照される PL/pgSQL 変数の値にあまり敏感でない場合にのみ発生します。もしそうなら、毎回計画を生成することは純利益です。ここから
その場合、一般的なプランを使用する必要がありますか? 毎回計画がないので速いですか、それとも遅いですか?少なくともそれらはキャッシュされます。私のクエリは動的であるため、変数に敏感ですが、
もしそうなら、毎回計画を生成することは純利益です。
実際に意味?EXECUTE
毎回 /planを使用することは、一般的なものよりも良いですか、それとも悪いですか? 「ネットウィン」は私を混乱させます。
一般的な計画が不正確で、EXECUTE
/planning が毎回遅くなる場合、わざわざ pl/pgsql を使用する必要はありません。次に、いくつかの if を使用して簡単なクエリを作成できます。
要するに、速度とプラン キャッシングの点でEXECUTE/plan each time
が優れているか劣っているかについては、結論を出すことはできません。generic cached plan
説明とアドバイスをお願いします、私は混乱しています。
参考までに、これは私が作成しているものです。mytables
そのまま動作しますが、およびの IF がさらに追加されます。mywhere
DROP FUNCTION IF EXISTS __aa(ii int, fk int);
CREATE FUNCTION __aa(ii int, fk int) RETURNS TABLE(id INTEGER,val text, fd integer) AS $$
DECLARE
myt text;
mytables text;
mywhere text;
BEGIN
mytables := 'dyn_tab2';
mywhere := 'dyn_tab2.id=$1';
IF fk IS NOT NULL
THEN
mywhere := mywhere || 'AND dyn_tab2.fk_id=$2';
END IF;
RETURN QUERY EXECUTE format('
SELECT dyn_tab2.id, dyn_tab2.value, dyn_tab2.fk_id
FROM %I WHERE ' ||mywhere,
mytables)
USING ii, fk;
END;
$$
LANGUAGE 'plpgsql';
ありがとう