MySQL の innodb_buffer_pool_size を適切に設定する
InnoDB のパフォーマンスに最も影響を与える設定が innodb_buffer_pool_size です。この値を適切に設定することで、ディスク I/O を大幅に削減できます。
バッファプールとは
バッファプールは、InnoDB がテーブルやインデックスのデータをキャッシュするメモリ領域です。データがバッファプール内にあれば、ディスクアクセスなしで読み取れます。
メモリから読み取り(マイクロ秒単位)
ディスクから読み取り(ミリ秒単位)
キャッシュヒット率が高いほど、クエリは高速に実行されます。
現在の設定を確認する
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';デフォルトは 128MB ですが、本番環境ではこれでは小さすぎることがほとんどです。
適切なサイズの決め方
一般的な指針は、専用データベースサーバーの場合、物理メモリの 70〜80% をバッファプールに割り当てるというものです。
innodb_buffer_pool_size = 11G〜12G
innodb_buffer_pool_size = 4G〜5G
innodb_buffer_pool_size = 1G〜2G
OS やその他のプロセスにもメモリが必要なので、全量を割り当てないように注意してください。
設定方法
my.cnf(または my.ini)に以下を追加します。
[mysqld]
innodb_buffer_pool_size = 12GMySQL 5.7.5 以降では、動的に変更することも可能です。
SET GLOBAL innodb_buffer_pool_size = 12884901888; -- 12GB in bytesキャッシュヒット率を確認する
設定が適切かどうかは、キャッシュヒット率で判断できます。
SHOW STATUS LIKE 'Innodb_buffer_pool_read%';以下の計算式でヒット率を算出します。
| 99% 以上 | 非常に良好 |
| 95〜99% | 良好 |
| 90〜95% | 改善の余地あり |
| 90% 未満 | バッファプール不足の可能性 |
innodb_buffer_pool_instances
MySQL 5.5 以降では、バッファプールを複数のインスタンスに分割できます。これにより、並行アクセス時のロック競合が減少します。
[mysqld]
innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8バッファプールが 1GB 以上の場合、インスタンス数を増やすことが推奨されています。各インスタンスが 1GB 以上になるように設定するのが目安です。
ウォームアップの問題
MySQL を再起動すると、バッファプールは空の状態からスタートします。データがキャッシュされるまで、しばらくパフォーマンスが低下します。
MySQL 5.6 以降では、シャットダウン時にバッファプールの内容を保存し、起動時に復元できます。
[mysqld]
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup = ONこれにより、再起動後もすぐに高いキャッシュヒット率を維持できます。
監視すべき指標
バッファプールの状態を継続的に監視しましょう。
SELECT
(1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests)) * 100 AS hit_ratio,
Innodb_buffer_pool_pages_free,
Innodb_buffer_pool_pages_total
FROM (
SELECT
MAX(IF(Variable_name = 'Innodb_buffer_pool_reads', Variable_value, 0)) AS Innodb_buffer_pool_reads,
MAX(IF(Variable_name = 'Innodb_buffer_pool_read_requests', Variable_value, 0)) AS Innodb_buffer_pool_read_requests,
MAX(IF(Variable_name = 'Innodb_buffer_pool_pages_free', Variable_value, 0)) AS Innodb_buffer_pool_pages_free,
MAX(IF(Variable_name = 'Innodb_buffer_pool_pages_total', Variable_value, 0)) AS Innodb_buffer_pool_pages_total
FROM performance_schema.global_status
) t;pages_free が常に 0 に近い状態が続くなら、バッファプールの増量を検討してください。
まとめ
バッファプールの適切な設定は、チューニングの中で最もコストパフォーマンスが高い施策の一つです。まずはここから見直してみてください。