PostgreSQL 9.6.5文書 | |||
---|---|---|---|
前のページ | 上に戻る | 第 15章パラレルクエリ | 次のページ |
あるクエリの最速の実行戦略がパラレルクエリであるとオプティマイザが決定すると、Gather ノードを含むクエリプランを作成します。 単純な例を示します。
EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; QUERY PLAN ------------------------------------------------------------------------------------- Gather (cost=1000.00..217018.43 rows=1 width=97) Workers Planned: 2 -> Parallel Seq Scan on pgbench_accounts (cost=0.00..216018.33 rows=1 width=97) Filter: (filler ~~ '%x%'::text) (4 rows)
どの場合でも、Gatherノードは正確に一つの子ノードを持ちます。 子プランは、プランの中で並列に実行される部分です。 Gatherノードがプランツリーの中で最上位にある場合は、クエリ全体が並列に実行されます。 Gatherノードがプランツリーの他の部分にある場合は、その部分だけが並列に実行されます。 上の例では、クエリはただ一つのテーブルにアクセスするので、Gatherノード自身以外では、たった一つのプランノードだけが存在します。 そのプランノードはGatherノードの子ノードなので、並列に実行されます。
EXPLAINを使って、プランナが選択したワーカーの数を見ることができます。 クエリの実行中にGatherノードに到達すると、ユーザのセッションに対応しているプロセスは、プランナが選択したワーカーと同じ数のバックグラウンドワーカープロセスを要求します。 ある時点で存在できるバックグラウンドワーカーの数は、max_worker_processesによって制限されるので、あるパラレルクエリが、プラン時よりも少ない数のワーカープロセスによって実行されたり、まったくワーカープロセスなしに実行されることがあり得ます。 最適なプランは利用可能なワーカーの数に依存することもあるので、これは低い性能をもたらす結果になるかもしれません。 これがしばしば起こるようなら、max_worker_processesを増やしてより多くのワーカーが同時に実行できるようにするか、 max_parallel_workers_per_gatherを減らして、プランナがより少ない数のワーカーを要求するようにすることを考慮してください。
与えられたパラレルクエリから起動されたすべてのバックグラウンドワーカープロセスは、Gatherノードの子孫であるプランの一部を実行します。 リーダーはそうしたプランの部分を実行するだけでなく、追加の任務が与えられます。 ワーカーが生成したすべてのタプルを読み込まなければなりません。 プラン中のパラレル部分が少数のタプルを生成する場合は、リーダーは追加のワーカーとほぼ同じように振る舞い、クエリの実行を高速化します。 反対にプラン中のパラレル部分が大量のタプルを生成する場合は、リーダーはワーカーが生成したタプルの読み込みと、Gatherノードより上位のプランノードが要求する追加の処理ステップに忙殺されるかもしれません。 そのような場合は、リーダーはプランの並列実行部分のごく一部しか処理しません。