最左前缀原则到底指什么
它不是“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更有筛选力,那索引设计本身就有问题,该把高区分度字段放最左。
范围查询会让右边列索引失效
这是最容易踩坑的地方:一旦联合索引中出现
>、
、<code>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”——它只说明走了索引,不说明走全了还是只走了一半。
