SQL関数
...より良い選択です:
-
単純なスカラークエリの場合 。計画することはあまりありません。オーバーヘッドを節約することをお勧めします。
-
セッションごとの単一(またはごく少数)の呼び出し 。 PL/pgSQLが提供しなければならないプリペアドステートメントを介したプランキャッシングから得られるものは何もありません。以下を参照してください。
-
通常、より大きなクエリのコンテキストで呼び出され、インライン化できるほど単純な場合 。
-
経験が不足している場合 PL/pgSQLのような任意の手続き型言語で。多くの人がSQLをよく知っており、SQL関数に必要なのはそれだけです。 PL/pgSQLについて同じことを言える人はほとんどいません。 (かなり単純ですが。)
-
少し短いコード。ブロックオーバーヘッドなし。
PL/pgSQL関数
...より良い選択です:
-
手順要素が必要な場合 または変数 明らかに、SQL関数では使用できません。
-
あらゆる種類の動的SQL 、ここでビルドして
EXECUTE
ステートメントを動的に。 SQLインジェクションを回避するには、特別な注意が必要です。詳細:- Postgres関数と準備されたクエリ
-
計算がある場合 再利用できます いくつかの場所で、CTEを目的のために伸ばすことはできません。 SQL関数では、変数がなく、繰り返し計算するか、テーブルに書き込む必要があります。 dba.SEに関するこの関連する回答には、コード例が並んでいます。 SQL関数/plpgsql関数/CTEを使用したクエリを使用して同じ問題を解決する場合:
- パラメータを関数に渡す方法
割り当ては、他の手続き型言語よりもいくらか高価です。必要以上の割り当てを使用しないプログラミングスタイルを採用します。
-
関数をインライン化できず、繰り返し呼び出される場合。 SQL関数とは異なり、クエリプランはキャッシュできます PL/pgSQL関数内のすべてのSQLステートメント。それらは準備されたステートメントのように扱われます 、プランは同じセッション内で繰り返される呼び出しのためにキャッシュされます(Postgresがキャッシュされた(汎用)プランのパフォーマンスが毎回再プランするよりも優れていると予想する場合。これがPL/pgSQL関数が通常は高速である理由です そのような場合の最初の数回の呼び出しの後。
これらの項目のいくつかについて説明しているpgsql-performanceのスレッドは次のとおりです。
- Re:pl / pgsql関数はSQL関数よりも優れていますか?
-
エラーをトラップする必要がある場合 。
-
トリガー関数の場合 。
-
オブジェクトを変更したり、後続のコマンドに関連する方法でシステムカタログを変更したりするDDLステートメントを含める場合-PL / pgSQL関数が各ステートメントを順番に計画および実行する間(プリペアドステートメントのように)、SQL関数のすべてのステートメントが一度に解析されるため。参照:
- PL / pgSQL関数には副作用があるのに、SQL関数にはないのはなぜですか?
また、考慮してください:
- PostgreSQLストアドプロシージャのパフォーマンス
実際に戻る PL / pgSQL関数から、次のように記述できます。
CREATE FUNCTION f2(istr varchar)
RETURNS text AS
$func$
BEGIN
RETURN 'hello! '; -- defaults to type text anyway
END
$func$ LANGUAGE plpgsql;
他の方法があります:
- 変数を使用せずにplpgsql関数に整数を返すようにできますか?
- 「関数からの復帰」に関するマニュアル