【SQL】DBのインデックスについて
今回は第八章「SQLにおける順序」についてですが、 このブログでは、今までの記事で賄えることと、機能も進化している点があるかと思いましたので割愛させて頂きます。
本では主に今までのノウハウを用いて、ナンバリングなどを解説しています。
抑えておくこととしては、以下を意識できていればよいかと思います。
SQLは伝統的に順序をもった数を扱う機能を持っていませんでした。 テーブルの行が順序を持たないと定義されていたことと、 業務的に意味を持たない連番はエンティティの属性とはみなされなかったことがあります。
しかし、近年のSQLでは連番などを扱うための機能が追加されてきているそうです。 だんだんと伝統的な集合指向に手続き型の考えをミックスした言語に変わっているということです。
そして第九章「更新とデータモデル」です。
こちらも今までの記事で賄える部分が多いはずです。 なので、こちらもまとめのみです。
今までと同様、実行計画を確認しながら効率のよいUPDATE文を組み立てることが重要です。 例えば、行列複数列更新するなら、複数列をリスト化して一度に更新するという方法が考えられます。
- SQLにおける更新の効率化の鍵は、行式、サブクエリ、CASE式、MERGE文
- モデル変更の方がスムーズに解決できる場合もあるが、苦労を伴う
何れにせよ、全ての問題を必ずしもコーディングで解決する必要はないということを意識しておくこと。
続いて第十章、最終章です。
こちらは、「インデックスについて」です。
インデックスは、その構造に基いて分類すると3つにわけられます。
- B-treeインデックス
- ビットマップインデックス
- ハッシュインデックス
B-tree
treeという単語がある通り、データを木構造で保持するタイプのインデックスです。 RDBにおいて主役であるといってもいいかもしれません。
以下のリンクにイメージが載っています。 B-trreもB+treeも本質は変わりないです。
では、どのような列に対してインデックスを作成するべきなのでしょうか?
列のカーディナリティと選択率
カーディナリティとは、値のばらつき具合を示す概念のことです。 最も高いのは、全ての行について値が異なる一意キーの列。 最も低いのは、値が1種類しか存在しない列です。 行が複数でも考え方は同じです。
選択率とは、特定の列の値を指定したときに行をテーブル全体の母体集合から、どの程度絞りこめるのかを示す概念です。
なので、
- 値がよくばらついてること (カーディナリティが高い)
- 少ない行に絞りこめること (選択率が低いこと)
これらで5%未満の絞りこめる条件ならばインデックスを作成価値があるかもしれないということです。 (例: 100レコード、キーpkey=1で指定すれば1件に絞りこめる = 1/100 = 0.01 = 1%)
インデックスが使用できない場合
場合によってはインデックスで逆に悪影響を及ぼすことがあります。
この場合の解決策としては、アプリケーション設計で対処することとデータマートなどです。
ビットマップインデックス
データをビットグラフに変換して保持するタイプのインデックス。
ハッシュインデックス
キーをハッシュ分散することで、等値検索を高速化することを目的にしたインデックス。
column指向なのかrow指向なのか
DBによってカラム指向(列)かロー指向(行)なのか認識しておく必要があります。 インデックスオンリースキャンを利用する際も行指向ならば結局フルスキャンするしかないからです。
まとめ
B+treeは基本でいろんなRDBに採用されていることがわかりました。 うまく高速化するのはカーディナリティと選択率次第ということも覚えておきましょう。 選択率が高かった場合は、インデックスオンリースキャンが有効でした。
この記事で最終章が終わりました。 非常に良書で、キャリアの長いエンジニア向けではありませんが、 若手でDBに触れているけど、なんとなくで操作している、なんて方にはピッタリな技術書かと思います。
AWSやGCPといったクラウドサービスが当たり前になってきましたが、 SQLやDBの基礎を固めていくことで、されらのサービスを利用した際(ドキュメントと読むなど)に なんとなく用語の意味がわかったり、理解度が増すのではないでしょうか。
- 前回の記事