🐘

複合インデックスを張ってみる

2022/09/08に公開

はじめに

あるテーブル設計をしている時に、複合(マルチカラム)インデックスを張った方がいいなと思い色々調べてみたので、それをまとめてみる。
より具体的な背景としては、対象テーブルの候補キーが複合キーであり、テーブル用途的に主キーは必要ないようなテーブルについて考えていると思っていただきたい。今後のレコードが増分の予測から、候補キーにインデックスを張っておきたいと思った。使用したRDBMSはMySQL。

複合インデックスを張ってみる

複合インデックスを張る際の注意点としては、列の順番である。

複合インデックスを定義する際に考えるべき最も重要なのは、そのインデックスを使えるSQL文ができるだけ多くなるように、 列の順番を決めることです。

https://use-the-index-luke.com/ja/sql/where-clause/the-equals-operator/concatenated-keys

つまり、複合インデックスをの対象カラムの中で、一部を使って検索する頻度が高いもの順に指定しておくことで、検索の際にインデックスが使用され効率よく結果を探せる可能性がある。
単一カラムにインデックスを張る際はカーディナリティが高いものに対して設計をしたりするが、複合インデックスの場合は検索時にインデックスが効果的に使用されるか、という観点をより注意する必要がありそう。

構文は以下。細かいオプションは公式ドキュメントを参照してください。

MySQL

create-multti-clumn-index.sql
CREATE INDEX idx_multi_column ON tt (col1, col2);

PostgreSQL

create-multti-clumn-index.sql
CREATE INDEX idx_multi)column ON tt (major, minor);

今回の事例では、対象カラムが候補キーであるためUNIQUE制約を設定することでも同等の効果が期待できると思い、実際にはUNIQUE制約を付与した。

まとめ

  • インデックスはカーディナリティ(データのばらつき)が大きいものに対し指定すると効果的に作用する
  • 複合インデックスを設定しているカラムの一部を使って検索を行う場合、作成したインデックスが使われるように設計しておくと良い
    • あまりカーディナリティの高い順に指定すると検索に使用されなかったり、検索効率が悪くなる可能性がある

参考ページ

https://tech.excite.co.jp/entry/2021/04/27/150029
https://dev.mysql.com/doc/refman/8.0/ja/multiple-column-indexes.html
https://www.postgresql.jp/document/14/html/indexes-multicolumn.html
https://dev.mysql.com/doc/refman/8.0/ja/create-index.html
http://dbflute.seasar.org/ja/manual/topic/dbdesign/surrogatekey.html

Discussion