10より古いバージョンのPostgreSQLは、単一のバックエンドで各クエリを実行します。これは、単一のスレッドを持つプロセスです。クエリに複数のCPUを使用することはできません。また、単一のクエリ内で達成できるI / Oの同時実行性にも多少の制限があり、実際にはビットマップインデックススキャンの同時I / Oのみを実行し、それ以外の場合は同時I/OをOSとディスクシステムに依存します。
PostgreSQL10+は並列クエリをサポートしています。執筆時点(PostgreSQL 12リリース)では、並列クエリは読み取り専用クエリにのみ使用されます。並列クエリのサポートにより、一部のタイプのクエリでかなり多くの並列処理が可能になります。
Pgは、多数の小さなクエリの同時ロードに優れており、そのようにシステムを飽和させるのは簡単です。1つまたは2つの非常に大きなクエリに対してシステムリソースを最大限に活用するのは得意ではありませんが、より多くの種類のクエリに対して並列クエリのサポートが追加されるため、これは改善されます。
並列クエリのない古いPostgreSQLを使用している場合、またはクエリが並列クエリのサポートの恩恵を受けていない場合:
あなたができることは、仕事をチャンクに分割し、それらを労働者に配ることです。あなたはこれを次のようにほのめかしました:
クエリを変更してpostgreを取得し、使用可能なすべてのCPUを使用して、異なる行の並列でGetStatisticを同時に計算できますか?
DBlink、PL / Proxy、pgbouncer、PgPool-IIなど、この種の作業を支援するように設計されたさまざまなツールがあります。または、自分で行うこともできます。たとえば、それぞれがデータベースに接続し、UPDATE ... WHERE id BETWEEN ? AND ?
重複しないID範囲でステートメントを実行する8人のワーカーを開始します。より洗練されたオプションは、キューコントローラに約1000 IDの範囲をUPDATE
その範囲のワーカーに渡してから、新しいIDを要求させることです。
64個のCPUは、64個の並行ワーカーが理想的であることを意味するわけではないことに注意してください。書き込みに関しては、ディスクI/Oも要因になります。UPDATE
トランザクションを使用するように設定するcommit_delay
と(このデータのビジネス要件に対して安全な場合)synchronous_commit = 'off'
、同期による負荷を大幅に減らすことができれば、I/Oコストを少し抑えることができます。それでも、64人の同時ワーカーをはるかに下回る最高のスループットが達成される可能性があります。
GetStatistic
おそらく現在のループの多い手続き型PL/pgSQL関数ではなく、インライン化可能なSQL関数またはビューに変換することで、関数を大幅に高速化できる可能性が高くなります。この機能を見せていただければ助かります。