【結論】
・インデックスとは、データベースの検索速度を上げる機能
・但し、使い方を誤れば、データベースのパフォーマンスを下げてしまう
・インデックスを設定する指針は下記3つ
-大規模なテーブルに対して作成する
-カーディナリティの高い列に作成する
-SQL文でWHERE句の選択条件、
または結合条件に使用されている列に作成する
【本題】
今回は、データベース設計における「インデックス」がテーマです。
※インデックスとは
データベースの機能の一つで、カラムに対して設定することで、
設定したカラムでの検索が高速になる。
例:usersテーブル内のnameカラムを検索した場合など
便利な機能ですが、下記の様なデメリットもあります。
・データを保存/更新する速度が遅くなる
データを保存する際に、設定されているインデックスの数だけ、
追加でデータを作成されるので、インデックスを設定するカラムが
増えるだけ、処理の速度が遅くなります。
・データベースの容量を使う
設定したカラムを検索しやすくする為のデータを、
追加で作成して保存するので、インデックスを多く設定すれば、
その分データが必要になり、容量が圧迫されます。
この様なデメリットにより、無闇にインデックスを設定してしまうと、
メリットよりデメリットの方が大きくなってしまう為、
設定するのは必要最低限に留めることが重要です。
「では、インデックスは、
どの様なデータに設定すれば良いのでしょうか?」
インターネットから情報を集めて見たのですが、
踏み込んだ説明が無かったり、逆に高度過ぎて訳が分からなかったりと、
ちょうど良い説明をしているサイトが見当たらない…
途方に暮れているところ、いい本を見つけました。
「達人に学ぶDB設計徹底指南書」
こちらの本では、
下記3つをインデックスを設定する指針として上げています。
-大規模なテーブルに対して作成する
-カーディナリティの高い列に作成する
-SQL文でWHERE句の選択条件、
または結合条件に使用されている列に作成する
・大規模なテーブルに対して作成する
「大規模」がどのくらいか?については、下記の様に記述されています。
「データ量が少ない場合」というのが
どの程度の閾値なのか、という所が気になるところです。
これは、ストレージやサーバーの性能など
環境要因によって変わる為に、
固定的な値は存在しないのですが、
最近のハードウェアを考えるなら、
目安としてはレコード数が1万件以下の場合は
ほぼ効果がないと考えてもらって構いません。
ただ、これはあくまで目安です。
実際の閾値はシステムによって異なる為、
あらかじめ簡単な実測を行って
感覚をつかむことをお勧めします。
1万件以上というのが、一般的に多いのか少ないのかというのが、
実務をしていないので、まだ分かりませんが、それ以下なら、
インデックスを敢えて設定する必要は、基本的に無さそうですね。
・カーディナリティの高い列に作成する
カーディナリティの高い列というのは、
カラムに格納されているデータの種類が多いという意味です。
例えば、「性別」であれば、「男」「女」「不明」の3つだけなので、
カーディナリティは低いと言えます。
逆に、「顧客番号」や「電話番号」など、レコード毎に
固有の情報であれば、カーディナリティは高いでしょう。
他にも、「受付日」など全て固有で無いとしても、
全体のレコード数を5%に絞りこめるのであれば、
カーディナリティは高いと言えるそうです。
但し、カーディナリティが高い場合でも、
特定の値にデータが集中している列は不向きです。
例えば、1~100までの値を取る列があったとして、
100が全体の99%に対して、1~99が1%の場合などです。
この時、1~99は、ほぼピンポイントで指定ができるのに対して、
100を検索するには非常に広範囲の検索を行わなければならないからです。
・SQL文でWHERE句の選択条件、
または結合条件に使用されている列に作成する
検索を高速化することがメリットですので、
SQLで検索条件や結合条件に使用されていないカラムに、
いくらインデックスを設定しても無意味です。
なお、SQLの記述次第でインデックスが機能しないケースがあるのですが、
これを詳しく説明し出すと長くなるので、興味のある方は、
「達人に学ぶDB設計徹底指南書」をご購入ください。
インデックスに限らず、データベース全般は興味深いテーマなので、
今後も色々勉強しようと思います。
(今回はやりませんが、実測もいつかやってみたいです)
《今日の学習進捗》
HamlとSassを使ってアプリのビュー作成
途中でデータベースにハマってしまう
学習開始からの期間 :28日目
今日までの合計時間:246.0h
今日までに到達すべき目標時間:255.7h
目標との解離:-9.7h
「10,000時間」まで、
残り・・・「9754時間!」