PostgreSQL 9.6.5文書 | |||
---|---|---|---|
前のページ | 上に戻る | 第 15章パラレルクエリ | 次のページ |
どのような状況においても、プランナにパラレルクエリプランを生成させなくしてしまう設定があります。 とにかくパラレルクエリプランを生成させるためには、次に示すように設定しなければなりません。
max_parallel_workers_per_gatherは0より大きい値に設定しなければなりません。 max_parallel_workers_per_gatherで設定した数以上のワーカーは使用されないという一般原則に含まれる個別のケースです。
dynamic_shared_memory_typeはnone以外に設定しなければなりません。 パラレルクエリは、協調動作するプロセスの間でデータのやり取りを行うために、動的な共有メモリが必要です。
加えて、システムはシングルユーザーモードで動いていてはいけません。 この場合はデータベースシステム全体が一つのプロセスで動いているので、バックグラウンドワーカーが使えません。
一般にパラレルクエリプランが生成可能な場合でも、以下のうち一つでも真であると、プランナはクエリに対するパラレルクエリプランを生成しません。
クエリがデータを書き込むか、データベースの行をロックする場合。 クエリがデータ更新操作をトップレベルあるいはCTE内で含むと、そのクエリに対するパラレルプランは生成されません。 これは現在の実装の制限で、将来のリリースでは解除される可能性があります。
クエリが実行中に一時停止する場合。 クエリの一部あるいは増分の実行が発生するとシステムが判断すると、パラレルプランは生成されません。 たとえば、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を超えてはいけない、という制限によってバックグラウンドワーカーが得られない場合。
クライアントが0ではないフェッチカウント付きのExecuteメッセージを送信した場合。 拡張問い合わせプロトコルの議論をご覧ください。 現在のlibpqにはそのようなメッセージを送る方法がないため、これはlibpqに依存しないクライアントを使った時にだけ起こります。 これが頻繁に起こるようなら、順次実行したときに最適ではないプランが生成されるのを防ぐために、それが起こりそうなセッションの中で、max_parallel_workers_per_gatherを設定すると良いかもしれません。
準備された文がCREATE TABLE .. AS EXECUTE ..文を使って実行される場合。 この構文は、読み取り専用操作であったはずのものを、読み書き操作に変換し、パラレルクエリには適さないものにします。
トランザクション分離レベルがシリアライザブルである場合。 この状況は通常は起こりません。 なぜならトランザクション分離レベルがシリアライザブルのときにはパラレルクエリプランは生成されないからです。 しかし、プランが生成されてから、実行されるまでの間にトランザクション分離レベルが変更されると起こる可能性があります。