Mímisbrunnr知恵の泉

← データエンジニアリング 一覧

🎓 レベル:発展 | 重要度:A(必須)

📎 前提:正規化と非正規化のトレードオフインデックスと実行計画 | 関連:ファイルフォーマットとシリアライゼーションデータウェアハウス

要点(BLUF)

概念 ── 同じ表、違う並べ方

論理的には同じテーブルでも、ディスク上の並べ方が違います。

flowchart TB
    subgraph ROW["行指向(OLTP向け)"]
      R["行1:1,Sato,East / 行2:2,Tanaka,West / 行3:3,Ito,East"]
    end
    subgraph COL["列指向(OLAP向け)"]
      C1["id列: 1,2,3"]
      C2["name列: Sato,Tanaka,Ito"]
      C3["region列: East,West,East"]
    end

行指向は「id, name, regionを1セットで連続」配置。列指向は「id だけ連続、name だけ連続、region だけ連続」配置です。

仕組み ── なぜ分析で速いか

「全顧客の amount 合計」を求めるとき:

flowchart LR
    Q["SUM(amount)を計算"] --> Rd["行指向:全列を読む(無駄なI/O大)"]
    Q --> Cd["列指向:amount列だけ読む(I/O最小)"]

実際、ファイルフォーマットとシリアライゼーション のラボでは、Parquet(列指向)から amount 列だけを読み出し、他列を触らずに合計(24975000)を得ています。「必要な列だけI/O」が列指向の第一の武器です。

第二の武器が圧縮。同じ列には同種の値(同じ型・似た範囲・繰り返し)が並ぶため、辞書エンコードやランレングス圧縮が劇的に効きます(CSV比でしばしば数倍小さい)。読むバイト数自体が減るので、さらに速くなります。

設計の勘所 ── ベクトル化と述語プッシュダウン

なぜそうするか ── クエリ形状に物理を合わせる

なぜOLAPで列指向を選ぶのか。分析クエリの形(少数列×多数行)に物理レイアウトを一致させると、読むデータ量そのものが最小化されるからです。インデックス(→ インデックスと実行計画)は「少数行を素早く特定」する道具ですが、分析は「大量行を全部なめて集計」するのでインデックスが効きにくい。そこで読む量を列で削る列指向が主役になります。OLTPとOLAPでストレージ方式が分かれるのは、クエリの形が正反対だからです。

⚠️ よくある落とし穴

対応ラボ

列だけ読むI/O削減と圧縮の実測は ファイルフォーマットとシリアライゼーション03_sql_optimization.py(Parquetからamount列のみ読込・合計確認済み)。

関連

第3章 SQLとクエリ最適化 目次