データベース 2024-04-01

データベースインデックスとは?仕組みと必要なタイミング

データベースインデックスとは何か、B-Tree・ハッシュインデックスの仕組み・効果的に使う場面・作り過ぎのデメリットを解説します。

Read in: en
データベースインデックスとは?仕組みと必要なタイミング

インデックスとは

テーブルに格納されているレコードを高速に取り出すための仕組み

以下のようなO(n)問題を抱えたクエリがあるとする。

SELECT * FROM users WHERE first_name = ‘Tom’

このクエリのパフォーマンスを上げるためには、以下のようにIndexを貼る。

ALTER TABLE users ADD INDEX (first_name)

メリット・デメリット

メリット

デメリット

データの作成・更新時には、同時にインデックスの追加・更新も行われるため、上記のようなデメリットが生じる。

インデックスのパターン

通常(1つのカラムに対して貼る)

ALTER TABLE users ADD INDEX (first_name)

部分的インデックス

容量の増加を抑えつつ、性能を向上させたい時に有効なパターン

最初の4バイトだけにインデックスを貼る例 ALTER TABLE users ADD INDEX (first_name(4))

マルチカラムインデックス(複合または合成インデックスとも呼ぶ)

ALTER TABLE users ADD INDEX (last_name, first_name)

MySQLでは、1つのクエリを実行する際、1テーブルについて1インデックスしか使用できないが、マルチインデックスを適用していれば、有効なインデックスがクエリ実行の際に選択される。

マルチカラムインデックスの先頭に指定するカラムはカーディナリティの高いものにしておくのが通常良い。

ユニークインデックス

NULLを除いて値が重複して出現しなくなる。 レコードの作成・更新において、全ての値を調べて同じ値が既に存在しないことを確認する。 MySQLでは、ユニークキーを指定するとユニークインデックスも指定される。

ALTER TABLE users ADD UNIQUE (first_name)

インデックスの効果測定

EXPLAIN句でクエリの実行計画を確認。

EXPLAIN SELECT * FROM users WHERE first_name = ‘Tom’

以下の項目を確認

インデックスの基準

インデックスを検討したほうが良いかもしれない判断基準をリストアップ。 あくまで推測するための基準なので、EXPLAINでの計測をしたほうが良い。

クラスタインデックスとセカンダリインデックス

クラスタインデックス

以下に該当するインデックスがクラスタインデックスとなる。

セカンダリインデックス

クラスタインデックス以外のインデックスをセカンダリインデックスという。 セカンダリインデックスには主キーの値が含まれている。 EXPLAINで計測することが前提がだが、主キーの値が含まれているので、カバンリングインデックスを狙う際は複合インデックスに主キーを含めなくてもセカンダリインデックスだけでカバリングインデックスになる可能性を覚えておくと良いかも。 cf. 知って得するInnoDBセカンダリインデックス活用術!

カバリングインデックス

クエリの実行結果に必要なすべてのカラムを含むインデックスのこと。

データファイルを読まず、インデックスだけでカバーできるので、検索が高速化される。

インデックスを貼る時の注意

インデックス列の演算やSQL関数

SELECT * FROM users WHERE amount * 2 > 10;

amountにインデックスを貼った場合、インデックスを活用するには演算子を避ける。amount自体がインデックスに保持されており、演算結果が保持されているわけではない。SQL関数についても同様。

SELECT * FROM users WHERE amount > 10/2;

IS_NULL

SELECT * FROM users WHERE amount IS NULL;

IS NULLやIS NOT NULLは基本的にはインデックスが有効に活用されない(DBMSの仕様に依る)。

否定形やOR

SELECT * FROM users WHERE amount <> 10;

否定形はインデックスを活用できない。ORについても同様。

LIKE

SELECT * FROM users WHERE name = 'a%';

LIKEを使う場合は、B-Treeの性質に依るため前方一致のみインデックスが活用される。

暗黙的な型変換

SELECT * FROM users WHERE age = '10'

ageが数値型の場合に文字列から数値に暗黙的な型がされるとインデックスが活用されなくなる。

参考

Tags: DB インデックス MySQL
Share: 𝕏 Post Facebook Hatena
✏️ View source / Discuss on GitHub
☕ サポート

このブログを応援していただける方は、以下からサポートをお願いします。いただいたサポートはブログ運営・技術研鑽に活用します。


関連記事