前回は非クラスター化インデックスを作って,実行プランでは「IndexSeek」と「RIDLookupになっていることを確認しました。前述した通り,SeekかScanに注目し,Scanなら全部読んでしまっている,Seekならピンポイントでうまく動いていると解釈してください。
Scanには「TableScan」だけでなく「IndexScan」というのも存在し,Indexとついているから,Indexがうまく動作しているように誤解するかもしれませんが,「Scan」なので,インデックスをすべて読んだという意味になります。これも,ポイントでは見つけられず,すべてを読んだということなので,インデックスをうまく使えていない状態です。
非クラスター化インデックスの内部構造
実表データ
非クラスター化インデックスの内部構造としては,まず,実表データ領域というものがあります。これはそのまま実際のデータで,SQLServerでは8キロバイトごとのファイルが複数ある形で存在しています。インデックスがない場合はこの実表データのみが存在していることになります。
非クラスター化インデックスを作成すると
非クラスター化インデックスを作成する,インデックスファイルが作成されます。今回のようにIdでインデックスを作成すると,Idの順序でインデックスファイルが作られます。インデックスファイルは,ツリー構造になっていて,「1~102」までは「インデックスファイルA」にあるよって感じで,次にインデックスAファイルを読むと「1から50はインデックスファイルA2にあるよ」って感じで,たどれるようになっています。そのインデックスファイルをたどっていくと,インデックスの終端があり,これを「リーフページ」と呼んでいます。
リーフページ
リーフページはインデックスの項目とRIDが入っています。今回の例であれば,Idのインデックスなので,「Id」と「RID」が入っていて,1~50までのIdとRIDが入っているという感じです。
RID
RIDとは実表データの行情報です。インデックスのリーフページには「Id」と「RID」しかないので,実表データから,社員データの姓名などを取ってこないといけません。そのために実表データがどのファイルの何行目にあるかという情報が入っています。先述の通り,実表データは8キロバイトの大量のファイルの集まりなので,どのファイルの何行目にデータがあるという情報があれば,ピンポイントでデータを取得することができます。こうやってインデックスファイルをツリー状にたどって,リーフページに行きつくことをIndexSeekといいます。要するに,インデックスをツリー状にたどり,ピンポイントにRIDを取得することで,どのファイルの何行目に欲しいデータがあるという事が分かります。そして,このRIDから必要なデータを取得することをRIDLockupといいます。
RIDLockup
インデックスのリーフページのRIDから実データの所在を割り出し,データを取りに行くことを,RIDLookupといい,社員テーブルをId指定で検索したときに,IndexSeek+RIDLookupになっていたという事は,「Id=1」で非クラスター化インデックスを探索し,ピンポイントでリーフページたどり着いたことをIndexSeekといい,そのIndexSeekしたリーフページにあるRIDで実データの場所を割り出し,実データを取りだしたことをRIDLookupと呼んでいます。なので,今回の非クラスター化インデックスは期待通りに機能したという事になります。
非クラスター化インデックスの内部構造(別表)
非クラスター化インデックスの内部構造を別の図で示します。前述の通り,ルートページからId順でたどり,リーフページにたどり着いた後に,RIDで実データを取得するという構造になります。