テーブルはディスクにどう置かれているか(ファイル・ページ・行ID)
ページとは、RDBがディスクとメモリのやり取りに使う固定サイズの単位(多くは8KB前後)で、複数行がまとめて格納される。ページは連続した数〜数十枚をまとめたエクステント単位で割り当てられ、行ID(ROWID / CTID)はページ番号とページ内オフセットの組で1行を一意に指す。
物理ストレージは 4 階層
RDBが扱うテーブルは、単なる行の一覧ではありません。実際にはディスク上でファイル → エクステント → ページ → 行の入れ子構造で保存されています。 インデックスの探索やフルスキャンの速さは、最終的にこの階層のどこにどれだけアクセスするかで決まります。
用語の注意: OS/ディスク側で「ブロック」と呼ばれる単位と、DB側の「ページ」はほぼ同じ意味で使われる。Oracleだけ「データブロック」という呼び方をするが、指しているものは他DBの「ページ」と同じ。本サイトでは以降「ページ」で統一する。
ファイル: 1テーブルは基本 1ファイル
1テーブルは概ね1つのファイルにマップされます。 ただしテーブルスペースやファイルグループなどの仕組みで、1テーブルが複数ファイルにまたがる設計もあります。
エクステント: ページの束・割り当ての単位
テーブルに新しい行を挿入していくと、ページが埋まってきて追加の領域が必要になります。 このときDBは 1 ページずつではなく 連続した複数ページをまとめて確保します。 この束が エクステント です。
エクステントを意識することで、 「クラスタ化インデックスの範囲検索がなぜシーケンシャルI/Oで済むのか」が物理的に理解できます。連続するページが同一エクステント内にあれば、ディスクヘッドを大きく動かさずに読める(あるいはSSDでも先読みが効く)からです。
ページ: ディスクとメモリのやり取りの単位
DBがディスクから読むときも、書くときも、単位はいつも 1ページまるごと。 1バイトだけ欲しくても、そのバイトが入っているページ全体を読み込みます。 だから「1ページに何行入っているか」がパフォーマンスの直接的な決定要因になります。
- ページ / ブロック
- ディスクI/Oの単位。1ページに複数行がまとまって入る。
- 行ID
(page, offset)の組。1行を一意に指すポインタ。- 物理I/O
- ページをディスクから読む操作。1回で数ミリ秒かかる。
行ID 2:1 が指すページを 1回のI/O で読み込み、その中から目的の行を取り出す。
行ID: 1行を指すポインタ
あるカラム値ではなく 物理的に1行を指す ためのIDが行IDです。 中身は(ページ番号, ページ内オフセット)の組。RDBMSごとに呼び方は違いますが、意味はどれも同じです。
なぜこれが重要かというと、インデックスの実体は「キー → 行ID」のマッピングだからです。 インデックスを引くと行IDが返ってきて、そのIDが指すページを1回読めば目的の行にたどり着けます。 インデックス探索が速いのは、この「1回のページ読み込みで済む」という物理的な事実に支えられています。
この理解が効いてくる場面
- B-tree: 葉ノードから行IDを引き、その行が入っているページを1回読む。
- クラスタ化インデックス: テーブル本体のページ並びそのものがキー順になっていて、連続エクステントを一気に読める。
- カバリングインデックス: 必要な列がインデックス側に入っているから、テーブル本体のページを読まなくていい。
- インデックスのコスト: 1回のランダムページ読み取りは連続読み取りの数十〜数百倍遅い、というのが更新コスト議論の前提。
よくある疑問
関連トピック
もっと深くDBを学びたい方へ。
たいてっくが、SQL・データベース設計・パフォーマンスチューニング・ IPAデータベーススペシャリスト対策まで、1対1で学習をサポートします。まずは無料相談から。