どのような状況においても、プランナにパラレルクエリプランを生成させなくしてしまう設定があります。 とにかくパラレルクエリプランを生成させるためには、次に示すように設定しなければなりません。
max_parallel_workers_per_gatherは0より大きい値に設定しなければなりません。
max_parallel_workers_per_gather
で設定した数以上のワーカーは使用されないという一般原則に含まれる個別のケースです。
加えて、システムはシングルユーザモードで動いていてはいけません。 この場合はデータベースシステム全体が一つのプロセスで動いているので、バックグラウンドワーカーが使えません。
一般にパラレルクエリプランが生成可能な場合でも、以下のうち一つでも真であると、プランナはクエリに対するパラレルクエリプランを生成しません。
クエリがデータを書き込むか、データベースの行をロックする場合。
クエリがデータ更新操作をトップレベルあるいはCTE内で含むと、そのクエリに対するパラレルプランは生成されません。
例外として、新しいテーブルを作成したりデータを追加したりする次のコマンドでは、そのクエリのSELECT
部分に対してパラレルプランが使用できます。
CREATE TABLE ... AS
SELECT INTO
CREATE MATERIALIZED VIEW
REFRESH MATERIALIZED VIEW
クエリが実行中に一時停止する場合。
クエリの一部あるいは増分の実行が発生するとシステムが判断すると、パラレルプランは生成されません。
たとえば、DECLARE CURSORで作られるカーソルは、決してパラレルプランを使用しません。
同様に、FOR x IN query LOOP .. END LOOP
のPL/pgSQLループは、決してパラレルプランを使用しません。
パラレルクエリが実行中に、ループの中のコードを実行しても安全かどうか、パラレルクエリシステムが判断できないからです。
クエリがPARALLEL UNSAFE
とマーク付されている関数を使っています。
ほとんどのシステム定義の関数はPARALLEL SAFE
です。
しかし、ユーザ定義関数はデフォルトでPARALLEL UNSAFE
とマーク付されます。
15.4の議論をご覧ください。
クエリが、すでにパラレル実行している別のクエリの内部で走っている場合。 たとえば、パラレルクエリから呼ばれている関数自身がSQLクエリを発行すると、そのクエリは決してパラレルプランを使用しません。 これは現在の実装の制限によるものですが、この制限を取り外すのは好ましくないかもしれません。 なぜなら、単一のクエリが非常に大きな数のプロセスを使用する結果となることがあり得るからです。
あるクエリに対してパラレルクエリプランが生成された場合でも、実行時にプランを並列に実行できないような状況があります。
この状況においては、まるでGather
ノードが存在しなかったかのように、リーダはGather
ノード以下部分のプランのすべてを自分自身で実行します。
これは、以下の条件のどれかが当てはまると起こります。
バックグラウンドワーカー数の合計がmax_worker_processesを超えてはいけない、という制限によってバックグラウンドワーカーが得られない場合。
パラレルクエリ目的で起動されたバックグラウンドワーカー数の合計がmax_parallel_workersを超えてはいけない、という制限によってバックグラウンドワーカーが得られない場合。
クライアントが0ではないフェッチカウント付きのExecuteメッセージを送信した場合。 拡張問い合わせプロトコルの議論をご覧ください。 現在のlibpqにはそのようなメッセージを送る方法がないため、これはlibpqに依存しないクライアントを使った時にだけ起こります。 これが頻繁に起こるようなら、順次実行したときに最適ではないプランが生成されるのを防ぐために、それが起こりそうなセッションの中で、max_parallel_workers_per_gatherを0に設定すると良いかもしれません。