InnoDB 的索引是 B+tree:一种平衡树,每个叶子都位于相同深度,且叶子之间相互链接以支持快速范围扫描。一次查找是 O(log n) —— 即使在超大的表上也只需读取少量页。
复合索引与最左前缀
复合索引 先按 ,再按 ,最后按 排序。你只能对这些列的使用它:、 或 —— 但单独用 或 ,因为在 固定之前,这些列并未排序。
InnoDB 的索引是 B+tree:一种平衡树,每个叶子都位于相同深度,且叶子之间相互链接以支持快速范围扫描。一次查找是 O(log n) —— 即使在超大的表上也只需读取少量页。
复合索引 先按 ,再按 ,最后按 排序。你只能对这些列的使用它:、 或 —— 但单独用 或 ,因为在 固定之前,这些列并未排序。
一个包含详细解答的 IT 面试题库——从初级到高级。
捐赠(a, b, c)abca(a, b)(a, b, c)b(b, c)aCREATE INDEX idx_abc ON events (user_id, status, created_at);
-- 会用到索引(最左前缀,最后一列上做范围)
SELECT * FROM events
WHERE user_id = 7 AND status = 'open' AND created_at > '2026-01-01';
-- 不会用到:跳过了最左列
SELECT * FROM events WHERE status = 'open';
列的排列顺序应把选择性最高的 / 等值条件放前面,范围列放最后:一旦遇到范围条件(>、BETWEEN),其后的列就无法用于查找定位。
如果一个索引包含了查询读取的每一列,InnoDB 就能仅凭索引给出结果 —— 无需回到聚簇索引。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 <- 覆盖,无需回聚簇索引查找
复合索引和覆盖索引是你把一个缓慢的多条件查询变成单次索引查找的手段。搞错列顺序 —— 或指望对第二个列的查询能用上索引 —— 是一个"存在的"索引却仍未被使用的最常见原因。