B+木インデックス設計と検索性能最適化(最左プレフィックス・カバリング)
索引は候補行の探索を減らす一方、保存容量と更新処理を増やします。検索列をすべて索引に入れるのではなく、よく使う条件、取得する列、結果の件数、更新頻度から設計します。B+木の構造を理解すると、複合索引の列順が探索範囲にどう影響するかを説明できます。
B+木と範囲検索
B+木では内部ノードが探索先を案内し、リーフにキーと行の参照情報などを保持します。リーフが同じ深さにある平衡木で、キー順のリーフをたどることで範囲検索を継続できます。具体的なキーの保持方法、リーフのリンク、分割方式はDBMSによって異なります。
等値検索では対象のリーフまで木を降り、範囲検索では開始位置を探して範囲の終わりまで進みます。索引を探す回数だけでなく、一致する行を読むコストが必要です。結果が表の大半を占める場合は、索引経由のランダムアクセスより全表走査が安いこともあります。
複合索引は辞書順に並ぶ
(顧客ID,注文日,注文番号)の索引では、まず顧客ID、同じ顧客の中で注文日、さらに同じ日の中で注文番号の順に並びます。顧客IDの等値条件と注文日の範囲条件なら、連続した範囲を絞りやすくなります。先行列に範囲条件があると、後続列の条件だけでは読む範囲を十分に狭められない場合があります。
検索条件 | 着眼点 |
|---|---|
顧客ID=10、注文日が9月 | 先頭の等値条件と次の範囲条件で候補を絞る |
注文日が9月のみ | 顧客ごとの位置が分かれる。先頭列なしのコストを確認する |
顧客ID>10、注文番号=100 | 顧客の範囲に含まれる多数のキーを読む可能性がある |
ただし「先頭列がなければ索引は一切使われない」という断定は誤りです。索引全体の走査や、製品・版・統計条件によってはスキップスキャンが選ばれます。PostgreSQL 18にも、先行列の値を内部的に切り替えて探索するスキップスキャンがあります。利用できることと、低コストになることは別です。
- 1. 不足列や可視性を確認
- 2. 必要列と条件がそろう
必要な情報が索引にあり、DBMSの追加確認条件を満たせる場合、表本体の取得を省けます。
カバリングと可視性の確認
検索・結合・出力に必要な列を索引が持つと、表本体からの列取得を減らせます。PostgreSQLのINCLUDEで非キー列を格納する場合、その列は探索順序を決める索引キーにはなりません。列を追加するほど索引が大きくなるため、少数の安定した取得列を中心に検討します。
PostgreSQLではIndex-Only Scanが選ばれても、可視性マップにより全行可視と確認できないページではヒープ取得が必要です。「カバリングにすれば表本体へのアクセスが常に0」とは限りません。更新の多い表では特にHeap Fetchesを確認します。
クラスタ化と更新コストを区別する
InnoDBのクラスタ化索引では、主キー索引のリーフに行データを格納し、二次索引には主キーを保持します。一方、PostgreSQLのCLUSTERは表を索引順へ一度並べ直す操作で、その順序を以降の更新でも自動維持するものではありません。同じ「クラスタ」という言葉でも構造と運用が違います。
索引追加後は、INSERT・DELETE・キー列UPDATEによる索引保守、ページ分割、ログ、キャッシュ占有を確認します。条件列を関数で包むと通常の索引が使いにくい場合がありますが、式索引が利用可能な製品もあります。検索条件の意味を保った書換えと、実際の計画の確認を組み合わせます。
演習1:等値と範囲の組合せ
条件:各顧客の9月の注文を検索する。条件は顧客ID=10、注文日>=9月1日かつ<10月1日。
問い:第一候補となる複合索引の順を挙げよう。
解答例:(顧客ID,注文日)。
根拠:顧客単位の範囲内で、日付の連続区間を探せる。ほかの主要クエリも含めて比較する。
演習2:Index-Only Scanの注意
条件:PostgreSQLで必要列を索引に入れたが、更新直後のページでHeap Fetchesが発生した。
問い:表本体を参照する理由を説明しよう。(35字以内)
解答例:可視性マップだけでは行の可視性を確認できないため。(25字)
根拠:列がそろうことと、MVCCの可視性を索引だけで判定できることは別である。
復習で確かめること
例の数値や業務条件を変えて同じ結論になるか確認してください。用語の定義だけでなく、問題文のどの条件から、どの制約・SQL・対策を選んだのかを自分の言葉で説明できれば、次の過去問に進みます。
出典と仕様を確認する
関連するテーマ
次におすすめの学習
編集・検証について
編集・検証:IT資格ラボ編集部
IPAが公開する試験要綱・シラバス・過去問題と、各技術の公式資料を優先して内容を確認しています。制度変更や誤りを確認した場合は、記事を見直して更新します。
編集方針・情報源・訂正方針を見る