当サイトはPR広告を利用しています。

【例付き】インデックスマージとは?【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 インデックスマージの最適化