-
2025-07-10 PostgreSQLPostgreSQL パラメータ
PostgreSQL のブロックサイズと処理性能への影響
PostgreSQLのブロックサイズ
PostgreSQL ではデータをページやブロックという単位で扱います。
例えば、id=1 のレコードを読み込もうとした場合、id=1 のデータだけを読み込むのではなく、id=1 のデータが格納されているページを読み込み、そのページから id=1 のデータを探し出すという動きになります。
PostgreSQL のデフォルト設定では 1 ページは 8 KB となっています。
ブロックサイズはコンパイル時に configure の --with-blocksize オプションで指定できます。
--with-blocksize オプションに指定できる値は 1 ~ 32 で、指定した値がブロックサイズのキロバイト数となります。
ただ、指定できる値は 2 のべき乗である必要があるため、3 や 5 など、2 のべき乗ではない値は指定できません。
未指定の場合は 8 が指定されたものとみなされます。
ブロックサイズの確認方法
現在のブロックサイズは、pg_config で configure のオプションを確認するか、pg_settings を参照することで確認できます。
以下に確認例を記載します。
# pg_config からブロックサイズを確認する
$ pg_config | grep CONFIGURE
CONFIGURE = '--with-blocksize=16' '--prefix=/usr/local/pgsql-17.4
# pg_settings からブロックサイズを確認する
postgres=# SELECT name, setting FROM pg_settings WHERE name = 'block_size';
name | setting
------------+---------
block_size | 16384
(1 row)
上記の方法より、ブロックサイズは 16 KB であることを確認できました。
ブロックサイズを変更した場合の影響
ブロックサイズを小さくすると、データを細かく取得することになりますのでディスク IO の回数が増えます。
逆にブロックサイズを大きくすると、データを取得する単位が大きくなりますのでディスク IO の回数は減ります。
簡単にまとめると下記のようになります。
ブロックサイズ | ディスク IO の回数 | 影響 |
---|---|---|
小さくする | 増える | インデックススキャンのような特定のデータを取得する処理が効率化する(可能性がある) |
大きくする | 減る | シーケンシャルスキャンのような連続するデータを取得する処理が効率化する(可能性がある) |
ただし、PostgreSQL においてブロックサイズを変更することは稀であり、特別な要件がない限り、デフォルトの 8 KB で問題ありません。
実際に検証
前述した通り、ブロックサイズが小さい方がインデックススキャンが効率化され、大きい方がシーケンシャルスキャンが効率化される、と考えられています。
これを実際に検証し、どの程度の性能差が発生するのかを確認しました。
環境
検証に利用した環境は下記の通りです。
- Rocky Linux 9.3
- PostgreSQL 17.4
検証の方法
pgbench のテーブルを利用して「インデックススキャン」「シーケンシャルスキャン」「pgbench のベンチマークテスト」をそれぞれ 5 回ずつ実行しました。
スケールファクタは 10 で行いましたので、pgbench_accounts テーブルのサイズはおおよそ 140 MB となります。
また、shared_buffers を 128 MB、1 GB、4 GB と変動させて検証を行いました。
検証結果
検証した結果の平均 tps をグラフ化したものを下記に記載します。
縦軸が平均 tps で、横軸がブロックサイズです。
結果からわかること
- ブロックサイズ = 1 で、shared_buffers = 1 GB の場合の処理性能が低い
- シーケンシャルスキャンの性能は、ブロックサイズに比例している
- ブロックサイズが 2 以上の場合、性能差はほぼないというレベル(10% ~ 20% 以内)
- インデックススキャンの性能とブロックサイズに、関連性は(ほぼ)見られない
- pgbench のベンチマークテストの性能とブロックサイズに、関連性は(ほぼ)見られない
以上の通り、シーケンシャルスキャンを高速化させたいからといってブロックサイズを大きくしようとしても、あまり効果が見込めないことを確認できました。
また、今回検証したインデックススキャンや pgbench のベンチマークテストの結果を見る限り、ブロックサイズを変動させても、あまり性能に影響はないということも確認できました。
ただ、ブロックサイズ = 1 で shared_buffers = 1 GB の結果から、ブロックサイズ = 1 とした場合には、性能劣化する可能性は高そうです。
※ ファイルシステムやディスクデバイス、OS の設定などによっても変動すると思いますので、あくまでインサイト社内の検証環境で検証した範囲内での確認結果となります。
まとめ
繰り返しとなりますが、特別な理由がない限り、基本的には PostgreSQL のブロックサイズはデフォルト 8 KB のまま運用されています。
予想通りの結果となりましたが、今回の検証結果を通じてブロックサイズを変更しなくても問題ないことを改めて確認できました。