##本記事の対象
MySQLでクエリのパフォーマンスを気にし始め、
index回りについて調べ始めたがいまいちピンとこない人向けの記事になります。
テーブルのストレージエンジンはInnoDBを前提としています。
##クラスタインデックスとセカンダリインデックス
InnoDBにおいて、一口にインデックスといっても
- クラスタインデックス
- セカンダリインデックス
の2種類があります。
MySQLやらInnoDBのインデックスの記事をググるで良い記事が色々と出てきますが、
上記について理解がないと割と内容にピンとこないことが多いんじゃないかなぁと思います。
##結論
InnoDBにおいて「クラスタインデックス」とは、ずばり「主キー」のことです。
それ以外のキー(ユニークインデックスなど)はすべて「セカンダリインデックス」です。
以下から「料理本」を例えて説明したいと思います。
##クラスタインデックス
クラスタインデックスは料理本でいう所の、「ページ番号」です。
料理本の内容は「ページ番号」によって整列されていますね。
同じ作品であれば、どの本でも「ページ番号」で整列された同じ内容です。
また、ページ番号が書かれたページ(紙)にレシピそのものが記載されてますね。(当たり前ですが)
これは言い換えるとクラスタインデックスでは、
キー(ページ番号)が示す場所(ノード)に、データ(料理のレシピ)そのものが格納されている、ということです。
##セカンダリインデックス
セカンダリインデックスは料理本でいう所の、「索引」です。
料理本では料理の名前で索引があり、「料理名」で整列されてますね。
料理名からページ番号を見つけることで目的の料理の作り方を知ることが出来ます。
これを言い換えると、
キー(料理名)が示す場所(ノード)には、主キー(ページ番号)が格納されている、ということです。
もし索引から卵焼きのレシピを調べるとき、
- セカンダリインデックス(索引)から卵焼きのレシピが載っているページ番号(主キー)を調べる
- 1をもとに、クラスタインデックス(ページ番号)から卵焼きのレシピがのっているページ(データ)を得る
という工程を取ることになります。
つまり、セカンダリインデックスから検索を行うと検索処理を2回行うこととなります。
なので、InnoDBでは主キーでの検索のほうがパフォーマンスが良いです。
セカンダリインデックスは実質あるテーブルに対して、「セカンダリキー」と「主キー値」を持つテーブルのようなものです。
※索引でいえば「料理名」と「ページ番号」です。
##Covering Index について
クラスタインデックスとセカンダリインデックスについての前提があるとインデックス回りを調べる際に色々と捗りますが、例としてCovering Indexをみてみます。
Covering Indexをググってみると
該当の問い合わせ(クエリ)をインデックスのみで解決できることを示す。
的な説明があっていまいちピンと来なかったりしますが、セカンダリインデックスについての前提があれば理解できます。
例えば、料理本から、「あ」で始まる料理の数を知りたいとします。
この場合セカンダリインデックス(索引)から「あ」で始まる料理を数えます。
次に、索引にあるページ番号をもとに、、、と思った処、索引を見るだけですでに目的が果たせていることにきがつきます。
つまり「クラスタインデックス」への検索が省略できました。
セカンダリインデックスで検索をすると本来2回の検索が必要となりますが、
Covering Indexが効いていると1回の検索で済むため、より高速です。
Covering Indexはクエリが「セカンダリインデックス」のみで解決できることを示しています。
また、セカンダリインデックスの知識があれば、
Covering Indexはクエリが「インデックスで定義されているカラム、もしくは主キーのカラム」のみ参照する場合に効く、という所部分も理解できるかと思います。