1. はじめに
目的は、PostgreSQLの postgresql.conf における主要なパラメータを理解し、環境に合わせた適切な初期設定・チューニングを行えるようになることです。
対象はデータベースのパフォーマンス改善に取り組む初心者〜中級者。
PostgreSQLは、インストール直後のデフォルト設定が非常に保守的(低スペックな環境でも安全に起動するため)になっています。そのため、サーバーのリソースを十分に活かすには、設定ファイルのチューニングが不可欠です。本記事では、性能に直結するメモリ周りや接続、ログの観測設定について解説します。
2. メモリ関連の主要パラメータ
システムリソースの中で最もパフォーマンスに影響を与えるのがメモリ設定です。まずは全体像を把握します。
2.1 パラメータ一覧と使いどころ
| パラメータ | 目安・推奨値 | 意味・使いどころ |
|---|---|---|
| shared_buffers | 物理メモリの25% | DB自身がデータをキャッシュする共有メモリ領域。OSキャッシュとのバランスが重要。 |
| work_mem | 4MB 〜 数十MB(用途次第) | ORDER BY や JOIN などのソート/ハッシュ操作で各セッションが使うメモリ。 |
| maintenance_work_mem | 物理メモリの5% (最大1〜2GB) | VACUUM や CREATE INDEX など、メンテナンス処理で使われるメモリ。 |
| effective_cache_size | 物理メモリの50% 〜 75% | オプティマイザが参考にするOSキャッシュサイズの目安(実際の確保はしない)。 |
2.2 shared_buffers の考え方
PostgreSQLが自身で管理するキャッシュ領域です。
- 設定方針: 公式ドキュメントでは、専用サーバーの場合、システムメモリの 25% を推奨しています。PostgreSQLはOSのページキャッシュも強力に活用するアーキテクチャのため、ここを大きすぎ(例えば70%など)に設定すると、かえってOS側のキャッシュが減りスワップ(ディスクへの退避)の原因になります。
- 例: メモリ16GBのサーバーなら shared_buffers = 4GB
2.3 work_mem の注意点
各クエリがソートやハッシュ結合を行うためのメモリです。
- 設定方針: 重要なのは、この値が 同時実行される処理(接続数やノード数)ごとに消費される 点です。むやみに大きくするとメモリ枯渇を引き起こします。
- 図: 現象と対応
- ログに temporary file 出力多発 → メモリ内でソートしきれずディスクI/Oが発生している兆候。work_mem の増量を検討する。
- OOM Killer 発生 → 接続数に対して work_mem が大きすぎる兆候。値を減らすか、最大接続数を制限する。
2.4 maintenance_work_mem の役割とチューニング
PostgreSQLの日常的なメンテナンス処理(不要領域を回収する VACUUM や、インデックスの作成、外部キーの追加など)で使われるメモリ領域です。
- 設定方針: 推奨値は物理メモリの5%(最大でも1GB〜2GB程度)です。これを適切に設定することで、自動で行われる autovacuum がスムーズに完了し、パフォーマンスの低下を未然に防ぐことができます。
- 実践テクニック: 数千万件のデータがあるテーブルに対して手動で CREATE INDEX を行う場合などは、事前にそのセッション(接続)だけ一時的にこの値を大きくする(例:SET maintenance_work_mem = ‘2GB’;)ことで、システム全体に影響を与えずに処理時間を大幅に短縮できます。
2.5 effective_cache_size の考え方(オプティマイザへのヒント)
このパラメータは、実際にメモリを「確保」するものではなく、PostgreSQLのクエリ実行計画を立てる機能(オプティマイザ)に対する「ヒント(目安)」として機能します。
- 設定方針: 物理メモリの50%〜75%程度を設定するのが一般的です。これは「PostgreSQLの共有バッファとOS自身のキャッシュを合わせれば、これくらいはメモリ上にデータが乗っているはず」という予測値です。
- 効果: この値を大きく設定すると、オプティマイザは「メモリ上にデータがあるなら、インデックスを使った検索が速いだろう」と判断しやすくなり、インデックススキャンが積極的に選ばれるようになります。逆に小さすぎると、ディスクから直接読み込む必要があると判断され、非効率な全件検索(Seq Scan)が選ばれやすくなってしまいます。
3. コネクションとWAL(トランザクションログ)関連
| パラメータ | 目安・推奨値 | 意味・使いどころ |
|---|---|---|
| max_connections | 100 〜 500程度 | クライアントからの最大同時接続数。 |
| wal_buffers | 16MB または -1 | WALをディスクに書き込む前のバッファ領域。 |
3.1 max_connections を増やしすぎない
- 分析・対処案: デフォルトは100です。「接続エラーが出たから」と数千などに設定すると、各接続がロックやメモリ領域を確保し、システムリソースが枯渇します。大規模なシステムでは、アプリケーション側やミドルウェアにコネクションプール(PgBouncerなど)を導入し、PostgreSQL本体への直接接続は最小限(数百程度)に抑えるのがベストプラクティスです。
3.2 wal_buffers でI/O待ちを軽減
- 設定方針: デフォルトは -1 (shared_buffers の約3%に自動設定)です。更新処理(INSERT や UPDATE)が頻繁に発生するシステムでは、上限目安の 16MB を明示的に設定することで、WAL書き込みによるディスクI/O待ちを軽減できます。
4. ログ・監視設定(ボトルネックの特定)
性能試験時や本番運用において「いつ・どのクエリが遅延したのか」を分析するため、ログ設定は事前に仕込んでおく必要があります。
# 1秒(1000ms)以上かかったクエリをログに出力する
log_min_duration_statement = 1000
# ロック待ちが1秒以上発生した場合にログに出力する
log_lock_waits = on
deadlock_timeout = 1000
- 分析ステップ: 1. log_min_duration_statement で出力されたスロークエリを特定する。
- 該当クエリに対して EXPLAIN ANALYZE を実行し、実行計画を確認する。
- Seq Scan(全件検索)が発生していればインデックスの見直しを、ディスクソートが発生していれば前述の work_mem の調整を検討する。
5. まとめ
PostgreSQLのパフォーマンスを引き出すには、ハードウェア環境を正しくデータベースに認識させることが第一歩です。
- shared_buffers や effective_cache_size でOS全体とのバランスを取る。
- work_mem や maintenance_work_mem は用途と実行頻度に合わせて無駄なく割り当てる。
- スロークエリやロック待ちのログを有効化し、いつでも観測・改善できる状態を作っておく。
実務では、アプリケーションの要件やサーバースペックを考慮し、これらのパラメータを調整して負荷テストに臨んでみてください。

-1.png)

コメント