【例付き】インデックスマージとは?【MySQL】

当サイトはアフィリエイト広告を利用しています。

インデックスマージについて、どういった機能なのかと公式リファレンスに記載されていた注意点も併せてお伝えします。

インデックスマージとは

インデックスマージとは複数のインデックスを利用してクエリを効率的に実行する最適化手法の一つです。複数のインデックスの利用の仕方ですが、複数のインデックスに対してそれぞれクエリを実行して取得した結果を組み合わせる形です。

インデックスマージという言葉だと複数のインデックスをくっつけるようなイメージを与えてしまいますが、そうではありません。実際はそれぞれのインデックスによって取得した結果の組み合わせという意味になります。

例えば以下のようなクエリの時にインデックスマージが利用される可能性があります。

SELECT * FROM users WHERE status = 'active' AND age < 30;

このクエリではWHERE句でstatusとageが利用されています。このstatusとageそれぞれに対しインデックスが作成されておりインデックスマージが採用された場合、statusのインデックスを利用してactiveなデータだけがまず取得され、ageのインデックスを利用して30歳未満のデータが取得され、それらの結果をAND条件で紐づけた結果を最終的なクエリの返却値として返します。

注意点

いくつか注意点を紹介してます。

必ずインデックスマージが採用されるとは限られない

WHERE句に含まれているカラムに対してすべてインデックスがあるからといって必ずしもインデックスマージが採用されるとは限りません。どのようにクエリを実行するのかはDBMSの一機能であるクエリオプティマイザが決めており、判断材料はテーブル内のレコード数、データの分布、クエリの内容、キャッシュの状態など多岐に渡ります。

これらの条件を踏まえたうえで、インデックスマージを利用するべきかを判断してくれているため、人が考えた時にはインデックスマージを使いそうな時であっても使わない可能性もあります。

インデックスマージが使われるかどうかはクエリオプティマイザがどんなクエリ実行計画を立てたのかを明らかにするEXPLAINコマンドで分かります。EXPLAINコマンドで出力される結果において、typeカラムの値が"index_merge"になっていればインデックスマージが使われます。

既知の制限事項がある

実際にインデックスマージを利用した方が良いような状況であったとしてインデックスマージが採用されない制限事項があることを公式ページが教えてくれています。

ANDやORで深くネストした複雑なクエリだと最適化されにくいとのことです。

書き換えの例として以下のものが挙げられています。

(x AND y) OR z => (x OR z) AND (y OR z)
(x OR y) AND z => (x AND z) OR (y AND z)

インデックスマージをクエリオプティマイザに採用させるためにはクエリ側の工夫も必要なようです。クエリ検討の際にはできるだけ複雑にならないようにしましょう。またクエリを最適化するにはサブクエリも大きく役立つので活用することをお勧めします。

参考

MySQL :: MySQL 8.0 リファレンスマニュアル :: 8.2.1.3 インデックスマージの最適化

直近でおすすめの本

直近十数冊読んだ中で一番おすすめの本です。

人が行動をするに至るまでのステップを科学的に分析した上で、その結果を習慣と紐付けて解説してくれている本です。

悪い習慣を断ち、良い習慣を継続する方法を詳細に説明してくれています。習慣が人を作っているので、この本の内容を実践できれば人生を大きく好転させられる気がしました。

この本の最初の方に説明があるのですが、複利という考え方があり毎日1パーセントだけの増加でもそれが続くととてつもない倍率になります。これは投資でよく用いられる概念ですが、良い習慣は未来への投資なので習慣にもあてはまります。良い習慣を身に付けるのは早ければ早いほど良いです。

私はまず長時間YouTubeを見てしまう習慣を断って、直近の業務に役立つITの勉強を習慣として身に付けよう思います。