web-dev-qa-db-ja.com

PostgreSQL手続き言語-PL / pgSQLとSQLの違い

誰かが違いを要約してください:

http://www.postgresql.org/docs/9.1/static/xfunc-sql.html

そして

http://www.postgresql.org/docs/9.1/static/plpgsql.html

主なポイント:

  • 概念の違い
  • 問題のある家族を考えると、使いやすさ
  • 政治的な問題
21
Gismo Ranas

PL/PgSQLとプレーンSQL関数はどちらもより大きなツールセットの一部であり、そのコンテキストで表示する必要があります。私はそれを、複雑さとコストの上昇と一致する力の昇順のスケールで考える傾向があります。そこでは、うまく機能する最も単純なツールを使用する必要があります。

  • 可能な場合はビューを使用する
  • ビューが適切でない場合は、SQL関数を使用します
  • SQL関数が適切でない場合は、PL/PgSQLを使用してください。
  • PL/PgSQLが制限されているか、表現力が十分でない場合は、PL/Perl、PL/Python、PL/V8、PL/Java、または好みの設定を使用してください。
  • ...そしてPLが仕事をしない場合は、外部プログラムを使用し、場合によってはLISTENNOTIFYを使用して通信します。

機能が必要だと思うときは、非常に頻繁にビューで十分です。ビュー全体をSELECTするのに非常にコストがかかる場合でも、通常、ビューを参照するクエリのWHERE句はビューにプッシュダウンされ、クエリプランが大きく異なる可能性があります。 SQL関数をビューに変換することで、パフォーマンスが大幅に向上しました。

ビューを使用できず、SQL関数を検討する必要があるのは、主に次の場合です。

  • WHERE式内のパラメーターのように、単純なWITH句として表現できないパラメーターが必要です
  • SECURITY DEFINER関数を介したセキュリティバリアが必要であり、PostgreSQL 9.2以降のsecurity_barrierビューではニーズに対応できません。
  • オプティマイザーによってビューのサブ句にプッシュダウンされないパラメーターが必要であり、それをより直接制御したい場合。または
  • Paramsがたくさんあるか、paramsの繰り返しがたくさんあるので、ビューとしてクエリを書くことは非現実的です。

これらのタスクのほとんどでは、プレーンなSQL関数が適切に機能し、多くの場合PL/PgSQLよりも読みやすくなっています。 STABLEまたはIMMUTABLEとして宣言された(およびSTRICTまたはSECURITY DEFINERとしても宣言されていない)SQL関数も、呼び出しステートメントにインライン化できます。これにより、関数呼び出しのオーバーヘッドが取り除かれ、呼び出し側関数のWHERE条件がオプティマイザによってSQL関数にプッシュダウンされると、パフォーマンスが大幅に向上する場合があります。タスクに十分な場合は常にSQL関数を使用します。

SQL関数が機能しない主なタイミングは、多くのロジックが必要な場合です。 CASEステートメントとして表現できないif/then/else操作、計算結果の再利用、チャンクからの値の構築、エラー処理など。PL/ PgSQLが便利です。次のように、SQL関数を使用できない場合、または関数が適切でない場合は、PL/PgSQLを選択します。

  • EXECUTEステートメントによる動的SQLおよび動的DDL
  • ログまたはクライアントのRAISEエラー/警告が必要な場合
  • 例外処理が必要な場合-トランザクション全体をエラーで終了させる代わりに、EXCEPTIONブロックでエラーをトラップして処理できます
  • CASE ... WHENにうまく適合しない複雑な条件付きロジック
  • WITHおよびCTEに適合できない計算値の再利用が多い
  • 動的レコードの作成
  • アクションを実行する必要がありますafter結果セットを生成します

共通テーブル式(CTE)、特に書き込み可能なCTEとWITH RECURSIVEを使用すると、SQLの方がはるかに表現力があり強力なので、以前よりPL/PgSQLを使用する方がはるかに少ないことがわかります。私はビューとプレーンSQL関数をより多く使用しています。プレーンSQL関数には複数のステートメントを含めることができることに注意してください。最後のステートメントは関数の結果です。

28
Craig Ringer

plpgsqlは、変数、ループ構造などを備えた本格的な手続き型言語です。SQL関数は、単なるサブクエリです。 SQL関数は、STABLEまたはIMMUTABLEとして宣言され、STRICTとしても宣言されていない場合、呼び出しクエリにinlinedとなることがよくあります。各参考文献に記載されていました。

8
kgrittn