web-dev-qa-db-ja.com

PostgreSQL関数の並列安全性は、データを更新する関数を対象としていますか?

関数並列安全を理解するのに問題があります。私はそれが何をしているのか理解できます-これは、関数が並列マスターノードによって実行されるかどうか、またはクエリが並列処理を完全に無効にするかどうかを指定することです。

しかし、私はそれをいつ使用するか理解するのに苦労しています。例を挙げましょう。テーブルを作成するだけで、データの更新や行の挿入を行わない関数があるとします。これの並行安全性は何としてマークされるべきですか?私はそれを並列安全であるとマークしようと思いますが、それではマニュアルが以下を並列制限付きとしてリストする理由を理解できません。

  • 共通テーブル式(CTE)のスキャン。
  • 一時テーブルのスキャン。

両方のポイントが必ずしもデータの更新/挿入(競合状態)を伴うわけではないので?

CTEのケースは特に奇妙です。 CTE呼び出しに並列セーフ関数を追加すると、並列セーフとして実行されなくなることを理解していますか?また、関数の並列安全以外では、すべてのCTEが並列制限として実行されることを理解していますか?ここに実体化されたCTEと実体化されていないCTEの間に違いはありますか?

2
Zeruno

その理由は、CTEと一時テーブルの両方が、それらを作成したバックエンドプロセスに対してプライベートであり、並列ワーカープロセスは、リーダープロセスのプライベートリソースにアクセスできない異なるプロセスであるためです。

CTEスキャンを並列で安全にするには、CTEを共有メモリで具体化する必要があります。

データベースにロックを作成するため、テーブルを作成する関数を並列セーフとして注意深くマークします。ワーカープロセスが互いにロックするように、競合が発生しないことを保証できますか?

2
Laurenz Albe

テーブルのみを作成し、データを更新したり、行を挿入したりしない関数があるとします

テーブルを作成するには、システムカタログに行を挿入する必要があります。この機能はPARALLEL UNSAFEです。

0
jjanes