この背後にある理由:PL/pgSQLがプリペアドステートメント内部としてSQL文を処理します。
まず:デフォルトの設定では、すべてでPL/pgSQL関数の内部SQL文のなしロギングがあります。 auto_explain
を使用していますか?
同じセッションにおける呼び出しの最初のカップル、SPIマネージャ(サーバプログラミングインタフェース)が実際パラメータ値に基づいて、新たな実行プランを生成します。どんな種類のログでも、パラメータ値がインラインに報告されます。
現在のセッションでは、実行計画が実際のパラメータ値に敏感でないように見える場合、Postgresは現在のセッションでいくつかの呼び出しを追跡し続け、一般的なキャッシュプランを再利用し始めます。次に、質問のように$n
パラメータを持つ準備済みの文の一般的なプランが表示されます。
chapter "Plan Caching" in the manualの詳細。
シンプルなデモで効果を確認できます。同じセッションで(必ずしも同じではないトランザクション):
CREATE TEMP TABLE tbl AS
SELECT id FROM generate_series(1, 100) id;
PREPARE prep1(int) AS
SELECT min(id) FROM tbl WHERE id > $1;
EXPLAIN EXECUTE prep1(3); -- 1st execution
あなたが実際の値表示されます:今、あなたは$n
パラメータが表示されます
Filter: (id > 3)
EXECUTE prep1(1); -- several more executions
EXECUTE prep1(2);
EXECUTE prep1(3);
EXECUTE prep1(4);
EXECUTE prep1(5);
EXPLAIN EXECUTE prep1(3);
を:
Filter: (id > $1)
したがって、現在のセッションの最初の数回の呼び出しで、パラメータ値をインライン化したのクエリを取得できます。
それとも、EXECUTE
で、動的SQLを使用することができますが、またper documentation:
、ので、EXECUTE
を介して実行するコマンドのためのプランのキャッシュはありません。 代わりに、コマンドは、そのステートメントが実行されるたびに常に計画されます。 したがって、コマンド・ストリングを関数 内で動的に作成して、異なる表および列に対してアクションを実行することができます。
実際にパフォーマンスに影響を与える可能性があります。
関連 :
私はあなたのログ形式を変更することができるとは思いません。パラメータを自分で置き換えるのではなく、[PREPARE'](https://www.postgresql.org/docs/current/static/sql-prepare.html)/ [' EXECUTE'](https://www.postgresql.org/docs/current/static/sql-execute.html)を参照してください。かなり簡単な正規表現を使って、これらのログ行を実行可能なスクリプトに変えることができるはずです。 –
@NickBarnes、ありがとう。スクリプトが唯一の解決策であると思われる。 – Nulik
必要に応じて、あなたのコードに['RAISE NOTICE'](https://www.postgresql.org/docs/9.6/static/plpgsql-errors-and-messages.html)(または類似のもの)を追加することができます。必要に応じて記録してください。 – joanolo