データベースのテーブルごとの容量を見積もる機会は、意外と多いです。
自前の MySQL サーバーで、かつ innodb_file_per_table=ON であれば、 テーブルごとの実ファイルサイズ(.ibd)を見ればある程度把握できます。しかし、Amazon RDS のようなマネージド環境ではファイルサイズを直接確認できません。
さらに、
- JSON カラムを持つ
- PHPクラスのシリアライズデータを格納している
- 可変長テキストが多い
といったケースでは、レコードごとのサイズが均一ではありません。 レコード数が増えるほど、容量の見積もりは難しくなります。
そんなときは information_schema.tables を利用します。
information_schema で平均行長を確認する
MySQL にはテーブルの統計情報が保持されています。
SELECT
table_schema,
table_name,
engine,
table_rows,
avg_row_length,
data_length,
index_length,
data_free
FROM information_schema.tables
WHERE table_schema = '<db_name>'
AND table_name = '<table_name>';
主なカラムの意味
| カラム | 意味 |
|---|---|
table_rows |
推定レコード数(InnoDBでは概算) |
avg_row_length |
平均行長(バイト) |
data_length |
データ領域サイズ(バイト) |
index_length |
インデックスサイズ(バイト) |
data_free |
未使用領域 |
⚠️ 注意点
table_rows は InnoDB では「概算値」です。正確な件数ではありません。
実データ量ベースで平均サイズを計算する
avg_row_length も参考になりますが、
より直接的に確認したい場合は data_length / table_rows を計算します。
SELECT
table_schema,
table_name,
table_rows,
data_length,
ROUND(data_length / NULLIF(table_rows, 0), 1) AS avg_row_bytes_est,
index_length,
ROUND(index_length / NULLIF(table_rows, 0), 1) AS avg_index_bytes_per_row_est
FROM information_schema.tables
WHERE table_schema = '<db_name>'
AND table_name = '<table_name>';
これで分かること
- 1レコードあたりの平均データサイズ(概算)
- 1レコードあたりの平均インデックスサイズ(概算)
- データ増加時のストレージ予測
例:
| table_rows | data_length | avg_row_bytes_est |
|---|---|---|
| 1,000,000 | 800,000,000 | 800 bytes |
→ レコードが100万増えると、約800MB増えると推測できる。
注意点
table_rows は正確ではない
InnoDB では統計値です。
正確な件数を知りたい場合は:
SELECT COUNT(*) FROM <table_name>;
ただし巨大テーブルでは重くなります。
JSON や BLOB がある場合
- レコードごとのサイズのばらつきが大きい
- 実際の増加傾向とズレる可能性がある
大量投入前には、サンプルデータで試算するのが安全です。
data_free に注意
data_free が大きい場合は、
- DELETE による断片化
- OPTIMIZE TABLE 未実行
といった可能性があります。
まとめ
RDS ではファイルサイズを直接確認できませんが、 information_schema.tables を使えば、
- 平均レコードサイズ
- インデックス増加量
- 将来の容量予測
を概算できます。
JSONやシリアライズデータを扱うテーブルでは特に有効です。
「レコードが増えたらどれくらい容量が増えるのか?」
これをざっくりでも把握できるだけで、ストレージ設計やRDSクラス選定の精度はかなり上がります。