【実務・中級編】 列指向ストレージの概念 – PostgreSQL

なぜ「全カラムSELECT」が罪深いのか?――PostgreSQLにおける行指向と列指向の深い話

やあ。最近、分析基盤のパフォーマンスチューニングに頭を悩ませている後輩から、「PostgreSQLって結局、何がどこに保存されてるんですか?」なんて質問を受けたんだ。

DBの深淵を覗こうとするいい姿勢だね。今日は、PostgreSQLの「行指向(Heap)」と、最近注目されている「列指向(Columnar)」の仕組みについて、現場の視点で噛み砕いて話してみようと思う。

—

1. 伝統的な「行指向(Heap)」の限界

PostgreSQLの標準的なストレージである「Heap」は、レコードを一行まるごと物理的に隣接させて保存する。

— こんなテーブルがあるとする
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT,
product_name TEXT,
price NUMERIC,
created_at TIMESTAMP
);

Heapストレージでは、`SELECT FROM orders` を実行すると、ディスクから1レコード分のデータ(id, user_id, product_name, price, created_at)がセットで読み込まれる。これは「特定の1件を取り出す」ときには最強だ。

でも、考えてみてほしい。「全ユーザーの売上合計(`SUM(price)`)を出したい」という分析クエリを投げたとき、DBはどう動く?
`price`カラムだけが欲しいのに、DBは`product_name`や`created_at`といった「今回不要なデータ」まで含めて、ディスクからメモリへ読み込んでしまうんだ。これが「I/Oの無駄遣い」の正体だよ。

2. 「列指向(Columnar)」がゲームを変える

列指向ストレージは、このアプローチを真逆にする。テーブルを「行」ではなく「列」ごとに切り離して保存するんだ。

  • 行指向: `[id, user, name, price, date], [id, user, name, price, date]…`
  • 列指向: `[id, id, id…], [user, user, user…], [price, price, price…]`

こうなると何が嬉しいか?
`SUM(price)`を計算するとき、DBは`price`のカラムファイルだけをピンポイントで読み込めばいい。データ量が1/10になれば、ディスクI/Oも1/10になる。これが分析クエリで「爆速」を実現するメカニズムだ。

3. なぜ「圧縮効率」が桁違いなのか?

列指向が速い理由はI/O削減だけじゃない。「圧縮率」が段違いなんだ。

行指向のデータは、型がバラバラ(Int、Text、Timestamp…)だから圧縮しにくい。でも、列指向なら同じ列には同じデータ型が並ぶ。
例えば「価格」のカラムなら、似たような数値が並んでいるよね。これをRLE(連長圧縮)やデルタ圧縮にかけると、驚くほど小さくなる。

ストレージが小さくなれば、メモリに乗るデータ量が増える。結果、物理ディスクを叩く回数がさらに減る。この好循環こそが、データ分析基盤のエンジニアが血眼になって追い求めている世界なんだ。

4. PostgreSQLでどう使う?(CitusやHydraの活用)

「じゃあPostgreSQLは分析に向かないの?」という話ではない。PostgreSQLには拡張機能がある。

例えば、`Hydra`のようなカラム指向ストレージエンジンを導入すると、PostgreSQLの作法を守りながら列指向の恩恵を受けられる。

— Hydraを使った列指向テーブルの作成例(イメージ)
CREATE TABLE orders_col (
id INT,
user_id INT,
price NUMERIC
) USING columnar; — ここがキモ

こうしておけば、普段はPostgreSQLの強力なSQLを使いながら、裏側では超高速な列指向処理が行われる。インデックスも「必要最低限」に絞れるようになるから、インデックス更新のオーバーヘッドも激減するよ。

—

先輩からのアドバイス:適材適所を忘れるな

最後に一つだけ釘を刺しておこう。
列指向は「分析」には最強だけど、「1行ずつの更新(UPDATEやINSERT)」は苦手だ。カラムごとにファイルを書き換える必要があるからね。

  • 行指向: OLTP向け。Webアプリのユーザー管理や決済処理など。
  • 列指向: OLAP向け。BIツールからの集計、DWHの分析クエリなど。

「何でもかんでも列指向にすればいい」と考えるのは素人だ。今のシステムが「何をしたいのか」を突き詰めて、ストレージの特性を選べるエンジニアになろう。

もし自分の担当しているDBが「やたらと重い集計クエリ」で悲鳴を上げているなら、まずは「このクエリ、本当に全てのカラムが必要か?」を疑うところから始めてみてくれ。それが、データベースエンジニアとしての第一歩だ。

さて、今日はここまで。何か深掘りしたい部分はあったかな?いつでも聞きに来てくれ。

コメント

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