最左前缀原则指只要查询包含联合索引最左列,索引就可能被使用;跳过中间列则其右列失效;范围查询(如>、

最左前缀原则到底指什么
它不是“WHERE 条件必须按索引顺序写”,而是:**只要查询中包含联合索引最左边的列(哪怕只有一列),索引就可能被用上;但一旦跳过中间某列,它右边的所有列索引失效**。
比如你建了联合索引 INDEX idx_city_age_name (city, age, name):
-
WHERE city = '北京'→ ✅ 用上索引(1列) -
WHERE city = '北京' AND age = 25→ ✅ 用上索引(2列) -
WHERE city = '北京' AND name = '张三'→ ✅ 但只用上city,name不走索引(跳过了age) -
WHERE age = 25 AND name = '张三'→ ❌ 完全不走这个联合索引(缺最左列city)
为什么 WHERE 条件顺序乱写也能命中索引
MySQL 查询优化器会自动重排 WHERE 子句中的条件顺序,只要所有字段都在联合索引里、且最左列存在,它就能识别并使用索引。
例如:WHERE age = 25 AND city = '北京' 和 WHERE city = '北京' AND age = 25 效果一样,都会走 (city, age, name) 的前两列。
但注意:这只是“能用上”,不代表性能最优——如果 city 区分度极低(比如全国 90% 都是“北京”),而 age 更有筛选力,那索引设计本身就有问题,该把高区分度字段放最左。
范围查询会让右边列索引失效
这是最容易踩坑的地方:一旦联合索引中出现 >、、BETWEEN 或 LIKE 前模糊('%abc'),MySQL 就停止向右匹配。
-
WHERE city = '北京' AND age > 25 AND name = '张三'→name列不走索引(age > 25是范围,截断右侧) -
WHERE city = '北京' AND age >= 25 AND name = '张三'→ 在 MySQL 8.0+ 多数情况下仍不走name,别依赖 >=/ - 真正稳妥的做法是:把范围条件放最后,或拆成两个查询,或改用覆盖索引减少回表
怎么验证你的 SQL 真的用了索引
光看 EXPLAIN 输出还不够,关键要看 key、key_len 和 Extra 字段:
-
key显示实际使用的索引名 → 确认没走错索引 -
key_len值对应索引使用了多少字节 → 比如city是 varchar(20),utf8mb4 下最多占 80 字节;若key_len = 80表示只用了city;若key_len = 82,说明还用了age(tinyint 占 2 字节) -
Extra出现Using index→ 覆盖索引,不用回表;出现Using where; Using index是理想状态;出现Using filesort或Using temporary就要警惕了
别只信“type 是 ref 就 OK”——它只说明走了索引,不说明走全了还是只走了一半。










