このインデックス、必要?不要?と聞かれ「いらなそうだけど、何が根拠になるのかな」と調べてふむふむと思ったこと。
複合インデックスは先頭以外のカラムだけ指定すると使われない
columnA
columnB
というインデックスがあったとして、
where columnB = 1
のようにしても、上記インデックスは利用されないらしい。
図で見るとわかりやすい。
検索上位にきた↓のサイトで、インデックスがどう格納されているのかイメージついた。
複合インデックスの落とし穴
(厳密には違うかもしれないが、カラムの一部だけだと使用されないことを一旦了解できれば良いので)
columnAの値が1の場合、columnBの値には10,20,30がある。
columnAの値が2の場合、columnBの値には10,20,30,40がある。
…
という格納がされているなら、columnBを指定してもインデックス使えないのは当然。
SQLで1個目のカラムを指定しないなら意味ないよね、という話。
↓Oracleのドキュメント。
索引および表クラスタに関するガイドライン - A.1.4 コンポジット索引の選択に関するガイドライン
カーディナリティを考える
カラムに格納されているデータの種類数をカーディナリティというらしい。
いわゆるdistinctして何件残るか、がカーディナリティ。
以下引用:カーディナリティについてまとめてみた
インデックスを作る時の目安は特定のカラム値を指定した時に、全体の 5%程度に絞り込めるだけのカーディナリティがあることである。
ふむふむ、なるほど。
性別の場合男女どちらを選んでも 1 / 2 = 50%となるので、インデックスを作成する意味はないし、むしろマイナスになるだろう。
うんうん。50%に絞り込んだらむしろ遅くなりそう。
フルスキャンってぐあーーって一気に読み込むけど、
索引経由だと飛び飛びのデータを選んで読み込むことになるよね。
…という解釈では曖昧すぎるので、調べてみると。
シーケンシャルアクセスとランダムアクセスっていうらしい。Silver DBAでやったなー。覚えてない。
津島博士のパフォーマンス講座 第6回 パフォーマンスの基礎である索引について 2011.04.20公開
引用の続き。
複合インデックスを貼る時は、 カーディナリティの高い順に貼っていくのが大事で、適当な順番にしてはいけない。
カーディナリティが低いと絞り込みの役割まるで果たしてない、ってよくわかりました。
件数が少ないならフルスキャンでよくね?
フルスキャンすぐ終わるのにわざわざ索引アクセスする必要ないよね、っていう。
ざっくり1万件、って情報。
適切なインデックスを張るために
まとめ
仕事してると作業多めでこういうの考える機会なくて、鈍ってるなーと思いました。
先日もアーキテクチャわからなくてトンチンカンになったことがあり、慌てて絵で見てわかるOracleの仕組みをぽちったのである。(半年前、以前の版読んで救われたので)
今日届いてちらっと読んだのですが、やっぱりわかりやすいので、アーキテクチャ学びたい方に超オススメ。
寝る前にぼちぼち進めたいなー。