InnoDBのインデックスはB+treeです。すべてのリーフが同じ深さにあり、リーフが連結されて高速な範囲スキャンを可能にする、平衡木です。検索はO(log n)で、巨大なテーブルでもわずかなページ読み取りで済みます。
composite indexとleftmost prefix
composite index は、まず、次に、次にの順で行をソートします。使えるのは列の(左端からの接頭)に対してだけです。すなわち、、は使えますが、単独やは。これらの列はが固定されるまでソートされないためです。
InnoDBのインデックスはB+treeです。すべてのリーフが同じ深さにあり、リーフが連結されて高速な範囲スキャンを可能にする、平衡木です。検索はO(log n)で、巨大なテーブルでもわずかなページ読み取りで済みます。
composite index は、まず、次に、次にの順で行をソートします。使えるのは列の(左端からの接頭)に対してだけです。すなわち、、は使えますが、単独やは。これらの列はが固定されるまでソートされないためです。
(a, b, c)abca(a, b)(a, b, c)b(b, c)aCREATE INDEX idx_abc ON events (user_id, status, created_at);
-- USES the index (leftmost prefix, range on the last column)
SELECT * FROM events
WHERE user_id = 7 AND status = 'open' AND created_at > '2026-01-01';
-- Does NOT use it: skips the leftmost column
SELECT * FROM events WHERE status = 'open';
列は選択性の高いもの/等値条件を先に、範囲条件の列を最後に並べます。範囲(>、BETWEEN)に当たると、それより後ろの列はシーク(探索)には使えなくなります。
インデックスがクエリの読むすべての列を含んでいれば、InnoDBはインデックスだけで応答でき、clustered indexへ戻る必要がありません。EXPLAINにはUsing indexと表示されます。
CREATE INDEX idx_cover ON events (user_id, status, id);
EXPLAIN SELECT id FROM events WHERE user_id = 7 AND status = 'open';
-- Extra: Using index <- covering, no clustered-index lookup
compositeとcovering indexは、遅い複数条件クエリを1回のindex seekに変える手段です。列の順序を誤ること、あるいは2番目の列だけを条件とするクエリがインデックスを使うと期待することは、「存在する」インデックスがそれでも使われない最もよくある理由です。
ジュニアからシニアまで、詳細な回答付きのIT面接質問ライブラリ。
寄付する