DBのインデックスについて、今までぼんやりと検索条件の効率化についてはしっていたのですが、もう少し掘り下げて理解する必要があるなと思い、メモります。
SQLServerのインデックスについてすごくまとまっていたページがあるので全体的に以下を参照させていただきました。
SQLServer【Index編】#S2_08_非クラスター化インデックスの作成
Contents
インデックスがきかない(適さない)ケース
インデックスのデメリットとしては更新処理が遅くなるなんてことが挙げられますが、それ以外に単純に検索効率が向上しない(or適さない)ケースもあります。
ここ以外の単発の条件以外に、インデックスが意味がないケースはレコードが少ない場合、データのばらつきが少ない場合ですね。
例えばマスターであっても極端に数がすくなかったり(1桁)、性別だったり(基本2種類しかない)場合は不要かと思われます。
インデックスの内部的な仕組み
インデックスをはれば、検索効率が向上するということは何となく理解されていると思うのですが、内部的な仕組みについて復習しておこうかと。
インデックスは索引と呼ばれますが、一般的にDBに貼るインデックスはB-treeインデックスといわれるもので、本当の索引とはやや違いデータを探しやすくするしくみですね。
上のような構造でデータを格納しているため、データが増えてもそれに対する検索量が上がりにくい仕組みになっています(データ量nに対して、検索アルゴリズムはlognで増えます)。
クラスター化、非クラスター化
インデックス内部にはクラスター化、非クラスター化というものがあります。
主な特徴としては、
クラスター化インデックス
- テーブル内に1つまで作成可能
- 非常に強力(単純なイコールだけでなく、範囲検索や演算子にもきく)
- 主キー制約で自動的に生成される
非クラスタインデックス
- ユニーク制約で自動的に決まる
- 1つのテーブルに999個まで作成できる
- 検索効率がクラスター化インデックスと比べると落ちる(B-tree+参照を見に行く。特に範囲検索や演算子で不利になる)
- ディフォルトのcreate index 文だとこちらが作成される
このページが最強にわかりやすかったので、リスペクトもかねてリンクを張ります。
クラスター化インデックス と 非クラスター化インデックスの違い
実行計画の見方
MySQLだとexplainで見るかと思うのですが、SQLServerの場合、現在のプロジェクトではSSMSを使ってみており、実行計画が図なんですよね・・・
なれないと苦労します・・
ポイントに関して、全体のSQLに関しては
- Seek(インデックスがきいている)、Scan(フルスキャン、あるいはそれに近く低速)
- サブツリーの推定コストが累計の推定コスト(CPUやI/Oのコストはその一部分)
一応図だけではなく、以下のコマンドでテキストでもみれるようですが、わかrにくいので図で頑張って慣れましょう・・・
1 2 3 |
SET SHOWPLAN_TEXT ON; GO select文 |