There are several settings that can cause the query planner not to generate a parallel query plan under any circumstances. In order for any parallel query plans whatsoever to be generated, the following settings must be configured as indicated. どのような状況においても、プランナにパラレルクエリプランを生成させなくしてしまう設定があります。 とにかくパラレルクエリプランを生成させるためには、次に示すように設定しなければなりません。
<xref linkend="guc-max-parallel-workers-per-gather"/> must be set to a
value that is greater than zero. This is a special case of the more
general principle that no more workers should be used than the number
configured via <varname>max_parallel_workers_per_gather</varname>.
max_parallel_workers_per_gatherは0より大きい値に設定しなければなりません。
max_parallel_workers_per_gather
で設定した数以上のワーカーは使用されないという一般原則に含まれる個別のケースです。
In addition, the system must not be running in single-user mode. Since the entire database system is running as a single process in this situation, no background workers will be available. 加えて、システムはシングルユーザモードで動いていてはいけません。 この場合はデータベースシステム全体が一つのプロセスとして動いているので、バックグラウンドワーカーが使えません。
Even when it is in general possible for parallel query plans to be generated, the planner will not generate them for a given query if any of the following are true: 一般にパラレルクエリプランが生成可能な場合でも、以下のうち一つでも真であると、プランナはクエリに対するパラレルクエリプランを生成しません。
The query writes any data or locks any database rows. If a query
contains a data-modifying operation either at the top level or within
a CTE, no parallel plans for that query will be generated. As an
exception, the following commands, which create a new table and populate
it, can use a parallel plan for the underlying <literal>SELECT</literal>
part of the query:
クエリがデータを書き込むか、データベースの行をロックする場合。
クエリがデータ更新操作をトップレベルあるいはCTE内で含むと、そのクエリに対するパラレルプランは生成されません。
例外として、新しいテーブルを作成したりデータを追加したりする次のコマンドでは、そのクエリのSELECT
部分に対してパラレルプランが使用できます。
CREATE TABLE ... AS
SELECT INTO
CREATE MATERIALIZED VIEW
REFRESH MATERIALIZED VIEW
The query might be suspended during execution. In any situation in
which the system thinks that partial or incremental execution might
occur, no parallel plan is generated. For example, a cursor created
using <link linkend="sql-declare">DECLARE CURSOR</link> will never use
a parallel plan. Similarly, a PL/pgSQL loop of the form
<literal>FOR x IN query LOOP .. END LOOP</literal> will never use a
parallel plan, because the parallel query system is unable to verify
that the code in the loop is safe to execute while parallel query is
active.
クエリが実行中に一時停止する場合。
クエリの一部あるいは増分の実行が発生するとシステムが判断すると、パラレルプランは生成されません。
たとえば、DECLARE CURSORで作られるカーソルは、決してパラレルプランを使用しません。
同様に、FOR x IN query LOOP .. END LOOP
のPL/pgSQLループは、決してパラレルプランを使用しません。
パラレルクエリが実行中に、ループの中のコードを実行しても安全かどうか、パラレルクエリシステムが判断できないからです。
The query uses any function marked <literal>PARALLEL UNSAFE</literal>.
Most system-defined functions are <literal>PARALLEL SAFE</literal>,
but user-defined functions are marked <literal>PARALLEL
UNSAFE</literal> by default. See the discussion of
<xref linkend="parallel-safety"/>.
クエリがPARALLEL UNSAFE
とマーク付されている関数を使っています。
ほとんどのシステム定義の関数はPARALLEL SAFE
です。
しかし、ユーザ定義関数はデフォルトでPARALLEL UNSAFE
とマーク付されます。
15.4の説明をご覧ください。
The query is running inside of another query that is already parallel. For example, if a function called by a parallel query issues an SQL query itself, that query will never use a parallel plan. This is a limitation of the current implementation, but it may not be desirable to remove this limitation, since it could result in a single query using a very large number of processes. クエリが、すでにパラレル実行している別のクエリの内部で走っている場合。 たとえば、パラレルクエリから呼ばれている関数自身がSQLクエリを発行すると、そのクエリは決してパラレルプランを使用しません。 これは現在の実装の制限によるものですが、この制限を取り外すのは好ましくないかもしれません。 なぜなら、単一のクエリが非常に大きな数のプロセスを使用する結果となることがあり得るからです。
Even when a parallel query plan is generated for a particular query, there
are several circumstances under which it will be impossible to execute
that plan in parallel at execution time. If this occurs, the leader
will execute the portion of the plan below the <literal>Gather</literal>
node entirely by itself, almost as if the <literal>Gather</literal> node were
not present. This will happen if any of the following conditions are met:
あるクエリに対してパラレルクエリプランが生成された場合でも、実行時にプランを並列に実行できないような状況があります。
この状況においては、まるでGather
ノードが存在しなかったかのように、リーダーはGather
ノード以下部分のプランのすべてを自分自身で実行します。
これは、以下の条件のどれかが当てはまると起こります。
No background workers can be obtained because of the limitation that the total number of background workers cannot exceed <xref linkend="guc-max-worker-processes"/>. バックグラウンドワーカー数の合計がmax_worker_processesを超えてはいけない、という制限によってバックグラウンドワーカーが得られない場合。
No background workers can be obtained because of the limitation that the total number of background workers launched for purposes of parallel query cannot exceed <xref linkend="guc-max-parallel-workers"/>. パラレルクエリ目的で起動されたバックグラウンドワーカー数の合計がmax_parallel_workersを超えてはいけない、という制限によってバックグラウンドワーカーが得られない場合。
The client sends an Execute message with a non-zero fetch count. See the discussion of the <link linkend="protocol-flow-ext-query">extended query protocol</link>. Since <link linkend="libpq">libpq</link> currently provides no way to send such a message, this can only occur when using a client that does not rely on libpq. If this is a frequent occurrence, it may be a good idea to set <xref linkend="guc-max-parallel-workers-per-gather"/> to zero in sessions where it is likely, so as to avoid generating query plans that may be suboptimal when run serially. クライアントが0ではないフェッチカウント付きのExecuteメッセージを送信した場合。 拡張問い合わせプロトコルの説明をご覧ください。 現在のlibpqにはそのようなメッセージを送る方法がないため、これはlibpqに依存しないクライアントを使った時にだけ起こります。 これが頻繁に起こるようなら、順次実行したときに最適ではないプランが生成されるのを防ぐために、それが起こりそうなセッションの中で、max_parallel_workers_per_gatherを0に設定すると良いかもしれません。