PostgreSQLでは、各接続に専用のバックエンドがあります。このバックエンドは、接続とセッションの状態を保持するだけでなく、実行エンジンでもあります。バックエンドは、横に置いたままにしておくのは特に安価ではなく、アイドル状態の場合でもメモリと同期のオーバーヘッドの両方がかかります。
特定のワークロード上の特定のPgサーバーに対して、アクティブに動作するバックエンドの最適な数があります。動作するバックエンドを追加すると、速度が上がるのではなく、速度が低下します。そのポイントを見つけて、バックエンドの数をそのレベル程度に制限する必要があります。残念ながら、これには魔法のレシピはありません。ほとんどの場合、ハードウェアとワークロードのベンチマークが含まれます。
それ以上の接続が必要な場合は、「接続状態」と「実行エンジン」を分離できるプロキシまたはプーリングシステムを使用する必要があります。2つの人気のある選択肢は、PgBouncerとPgPool-IIです。アプリからプロキシ/プーラーへの軽量接続を維持し、データベースサーバーが最適な負荷で動作し続けるようにワークロードをスケジュールすることができます。入ってくるクエリが多すぎる場合、リソースを奪い合ってサーバー上のすべてのクエリの速度を落とす代わりに、実行されるまで待つものもあります。
postgresqlwikiを参照してください。
ワークロードがほとんど読み取られる場合、特に頻繁に変更されないアイテムがあり、信頼できるキャッシュ無効化スキームを決定できる場合は、memcachedまたはRedisを使用してデータベースのワークロードを減らすこともできます。これには、アプリケーションの変更が必要です。PostgreSQLのLISTEN
とNOTIFY
は、適切なキャッシュの無効化を行うのに役立ちます。
多くのデータベースエンジンには、実行エンジンと接続状態の分離がコアデータベースエンジンの設計に組み込まれています。Sybase ASEは確かにそうですし、Oracleもそうだと思いますが、後者についてはよくわかりません。残念ながら、PostgreSQLの接続ごとに1つのプロセスのモデルのため、バックエンド間で回避策を渡すのは簡単ではなく、PostgreSQLがこれをネイティブに行うのが難しくなるため、ほとんどの人がプロキシまたはプールを使用します。
PostgreSQLHighPerformanceを読むことを強くお勧めします。私はGregSmithや発行元とは何の関係もありません*。DBのパフォーマンスが気になる場合は、すばらしいと思います。
* ...まあ、私がこれを書いたとき、私はしませんでした。私は今同じ会社で働いています。