はじめに
この記事では、IBM Db2のインデックスの内部実装を深掘りします。
シリーズ最終回です。Db2はMDC(Multi-Dimensional Clustering)やカラムオーガナイズド表など、独自のデータ配置最適化機能を持っています。Db2 11.5を中心に解説します。
テーブル構造とインデックス
Db2のテーブルはPostgreSQLやOracleと同じくHeap構造がデフォルトです。
Db2用語 InnoDB用語 PostgreSQL用語
──────────────────────────────────────────────────────────
Regular Table Clustered Index Heap
RID (Record ID) ― ctid
Index Secondary Index Index
MDC Table ― ―
Column-organized Table ― ―
RID(Record ID)
行の物理位置を表す識別子です:
RID = Page Number + Slot Number
インデックスのリーフにはキー値とRIDが格納されます。PostgreSQLのctid、OracleのROWIDと同じ仕組みです。
B+Tree Index
Db2のインデックスはB+Treeです(InnoDBと同じ名称)。
基本構造
[Root Page]
| 100 | 200 |
/ | \
[Leaf Page] [Leaf Page] [Leaf Page]
10,RID 100,RID 200,RID
20,RID 120,RID 250,RID
50,RID 150,RID 300,RID
↔ ↔ ↔
INCLUDE列
Db2もSQL ServerやPostgreSQLと同様にINCLUDE列をサポートします:
CREATE INDEX idx_name ON employees(name) INCLUDE (department_id);
-- このクエリはIndex-Only Accessで完結
SELECT name, department_id FROM employees WHERE name = 'Alice';Db2では「Index-Only Access」と呼びます(SQL Serverの「Covering Index」、PostgreSQLの「Index Only Scan」に相当)。
オンラインインデックス再編成
-- オンラインでインデックスを再編成(サービス停止不要)
REORG INDEXES ALL FOR TABLE employees ALLOW WRITE ACCESS;MDC(Multi-Dimensional Clustering)
Db2の最もユニークな機能がMDCです。
MDCとは
テーブルのデータを複数のカラムの値の組み合わせに基づいて物理的にクラスタリングします。
CREATE TABLE sales (
sale_date DATE,
region VARCHAR(20),
product_id INT,
amount DECIMAL(10,2)
) ORGANIZE BY DIMENSIONS (sale_date, region);仕組み:Block Index + Cell
MDCテーブルでは、ディメンションの値の組み合わせごとにCell(ブロックの集合)が作られます:
region=East region=West
sale_date=2026-01 [Block1,Block2] [Block3]
sale_date=2026-02 [Block4] [Block5,Block6]
sale_date=2026-03 [Block7] [Block8]
各ディメンションにBlock Indexが自動作成されます。Block Indexは通常のB+Treeと違い、リーフが個々のRIDではなくBlock IDを指します:
通常のIndex: key → [RID1, RID2, RID3, ...] (行単位)
Block Index: key → [Block1, Block2, ...] (ブロック単位)
MDCの利点
-- この検索は region='East' のブロックだけスキャン
SELECT * FROM sales WHERE region = 'East';
-- 2つのBlock Indexの結果をビット演算で結合
SELECT * FROM sales WHERE region = 'East' AND sale_date = '2026-01-15';- ブロック単位のスキャンでI/Oが大幅に削減
- 複数ディメンションの組み合わせ検索が高速
- データの物理配置が自動的に維持される(INSERTで適切なCellに配置)
各DBのクラスタリング比較
| InnoDB | PostgreSQL | Oracle | SQL Server | Db2 | |
|---|---|---|---|---|---|
| 自動クラスタリング | PK順(常に) | なし | なし | Clustered Index順 | MDC(多次元) |
| 手動クラスタリング | ― | CLUSTER | ― | ― | REORG |
| 維持 | 自動 | 維持されない | ― | 自動 | 自動(MDC) |
カラムオーガナイズド表(BLU Acceleration)
Db2 10.5で導入された列指向ストレージです。SQL ServerのColumnstore Indexに相当します。
CREATE TABLE sales_analytics (
sale_date DATE,
region VARCHAR(20),
amount DECIMAL(10,2)
) ORGANIZE BY COLUMN;内部構造
Column Group 1: sale_date列 [2026-01-01, 2026-01-02, ...] (圧縮済み)
Column Group 2: region列 [East, West, East, ...] (辞書圧縮)
Column Group 3: amount列 [100.00, 250.00, ...] (圧縮済み)
- Synopsis Table:各カラムの最小値/最大値を保持(Data Skipping用)
- 辞書圧縮:カーディナリティの低いカラムに特に効果的
行指向 vs 列指向の選択
| 行指向(デフォルト) | 列指向 | |
|---|---|---|
| OLTP(INSERT/UPDATE) | ✅ 高速 | ❌ 遅い |
| 分析クエリ(集計) | ❌ 全列読み込み | ✅ 必要な列だけ読む |
| 圧縮率 | 普通 | 高い(10x〜) |
| 用途 | トランザクション処理 | DWH/分析 |
まとめ:インデックスシリーズ全体比較
| トピック | InnoDB | PostgreSQL | Oracle | SQL Server | Db2 |
|---|---|---|---|---|---|
| テーブル構造 | Clustered Index | Heap | Heap(IOT可) | Clustered or Heap | Heap(MDC/列指向可) |
| 主要インデックス | B+Tree | B-tree, GiST, GIN | B-tree, Bitmap | B-tree, Columnstore | B+Tree, Block Index |
| INCLUDE列 | なし | あり(11〜) | なし | あり | あり |
| 条件付きIndex | なし | Partial Index | なし | Filtered Index | なし |
| NULLの扱い | 含む | 含む | 全キーNULL除外 | 含む | 含む |
| 列指向 | なし | なし | In-Memory | Columnstore | カラムオーガナイズド表 |
| 多次元クラスタリング | なし | なし | なし | なし | MDC |
| DWH向け | なし | BRIN | Bitmap | Columnstore | MDC + 列指向 |
5つのDBを比較すると:
- InnoDB:Clustered Index一本のシンプルな設計。全テーブルがB+Tree
- PostgreSQL:最も多様なインデックスタイプ(B-tree, GiST, GIN, BRIN, SP-GiST, Hash)
- Oracle:Bitmap IndexとIOTが独自。NULLの扱いに注意
- SQL Server:Columnstore Indexが強力。INCLUDE列とFiltered Indexの実用性が高い
- Db2:MDCによる多次元クラスタリングが唯一無二。列指向ストレージも統合