【実務・中級編】 データ型の配置とパディング – PostgreSQL

「ねえ、ちょっといいかな。テーブル設計の時、カラムの順番ってどうやって決めてる?」

ふと後輩のコードレビューをしていて思ったんだ。多くのエンジニアが、「なんとなくドキュメントの順番」とか「思いついた順」でカラムを並べている。機能的には全く問題ない。でもね、PostgreSQLのパフォーマンスを極限まで絞り出そうとするなら、実は「カラムの並び順」は非常に重要なんだ。

今日は、データモデリングの裏側にある「アライメント」と「パディング」の話をしよう。これを知っているだけで、数百万件、数億件のテーブルになった時のストレージ効率やメモリ効率が劇的に変わるんだ。

—

CPUは「きりのいい数字」が好き

まず、なぜカラムの順序でサイズが変わるのか。答えは「メモリのアライメント(境界調整)」にある。

CPUはメモリからデータを読み込むとき、1バイトずつちまちま読むよりも、4バイトや8バイトの塊で一気に読み込む方が圧倒的に速い。だから、PostgreSQLの内部でも、各データ型には「境界」というルールがあるんだ。

例えば、`BIGINT`(8バイト)は8バイト境界に配置される必要があるし、`INTEGER`(4バイト)は4バイト境界に配置される。もし、サイズの小さい型と大きい型を無造作に並べると、CPUが読み込みやすいように、その間に「パディング(詰め物)」という名の隙間が勝手に挿入されるんだよ。

これが「見えない無駄」の正体だ。

—

実際に実験してみよう

言葉だけじゃピンとこないよね。こんなテーブルを考えてみて。

— 最適化されていない、パディングだらけのテーブル
CREATE TABLE bad_table (
is_active BOOLEAN, — 1バイト
val_big BIGINT, — 8バイト
is_deleted BOOLEAN — 1バイト
);

このテーブル、合計で10バイトくらいに見えるよね? でも、実際にはこうなっているんだ。

1. `is_active` (1バイト)
2. パディング (7バイト) ← BIGINTを8バイト境界に合わせるための無駄!
3. `val_big` (8バイト)
4. `is_deleted` (1バイト)
5. パディング (7バイト) ← 次のレコードのために調整が必要

結果、なんと24バイトも消費している。本来なら10バイトで済むはずが、2倍以上の容量を食っているわけだ。これが1億行あったらどうなると思う? 数百メガバイト、あるいはギガバイト単位で無駄なストレージを使い、ディスクI/Oを圧迫する。キャッシュ効率も当然落ちるよね。

—

魔法のレシピ:「大きい順」に並べる

じゃあ、どうすればいいか。答えはシンプル。「大きい順に並べる」こと。これだけで劇的に変わる。

— 最適化されたテーブル
CREATE TABLE good_table (
val_big BIGINT, — 8バイト
is_active BOOLEAN, — 1バイト
is_deleted BOOLEAN — 1バイト
— ここで合計10バイト。残りの6バイトは構造の末尾に少しだけ入るけど、劇的に減る
);

こうすると、パディングが最小限に抑えられる。8バイトのBIGINTの後に1バイトのBOOLEANを置いても、まだ8バイトの枠内に余裕があるから、そこに詰め込めるんだ。

実務での鉄則はこれだ。

  • 固定長でサイズの大きいもの(BIGINT, TIMESTAMP, UUIDなど)を上に持ってくる。
  • 可変長型(TEXT, VARCHARなど)や、サイズの小さい型(BOOLEAN, SMALLINTなど)を下に集める。

—

でも、過剰最適化には注意してね

ここまで話しておいてなんだけど、一つだけ釘を刺させてくれ。

「じゃあ今すぐ全テーブルを書き直そう!」と意気込むのは待ってほしい。このテクニックは、「膨大なレコード数を抱えるテーブル」や「頻繁にフルスキャンが発生するテーブル」でこそ真価を発揮するんだ。

数千件程度のマスタテーブルでこれをやっても、得られるメリットは微々たるもの。それよりも、アプリケーションの可読性や、後から追加するカラムの管理しやすさを優先するべきだ。

エンジニアリングは常にトレードオフ。

「どこがボトルネックか?」を冷静に見極めて、ここぞという時にこの「アライメントの知識」を武器として抜く。それが、熟練したエンジニアの振る舞いだと思うよ。

もし今のプロジェクトで、「なんかこのテーブル、妙に肥大化してるな?」と感じたら、まずは `pg_column_size` 関数で調べてみて。そして、カラムの並び順を少し入れ替えるだけで、驚くほどスリムになる瞬間を体験してみてほしい。

それじゃ、今日はこの辺で。また何か面白い設計の悩みがあったら聞かせてくれよ!

コメント

タイトルとURLをコピーしました