mysql最左前缀原则是联合索引生效的硬性门槛:查询必须从索引最左列开始且连续,否则失效;b+树有序结构决定只能从a切入,范围或函数操作会截断后续列匹配。

MySQL 最左前缀原则不是“建议”,而是联合索引能否生效的硬性门槛:只要查询条件没从索引最左列开始,或者中间跳过了某列,对应部分索引就直接失效——哪怕你建了 (a, b, c),WHERE b = 1 AND c = 2 也会全表扫描。
联合索引 (a, b, c) 哪些 WHERE 条件能走索引?
本质是 B+ 树的有序结构决定的:数据按 a 排序,a 相同时再按 b 排序,a 和 b 都相同时才按 c 排序。所以查找必须从 a 入口切入。
-
WHERE a = 1→ 走索引(只用到a) -
WHERE a = 1 AND b = 2→ 走索引(用到a, b) -
WHERE a = 1 AND b = 2 AND c = 3→ 走索引(完整匹配) -
WHERE a = 1 AND c = 3→c列不走索引(跳过b) -
WHERE b = 2 AND c = 3→ 完全不走索引(没a,无入口)
LIKE、范围查询和函数操作会截断匹配链
一旦遇到范围条件(>、、<code>BETWEEN、非前缀 LIKE),后续列立刻失效——这不是 MySQL 故意卡你,而是 B+ 树无法在“范围”之后继续保证右侧列的有序性。
-
WHERE a = 1 AND b > 10 AND c = 3→ 只有a和b生效,c不走索引 -
WHERE a = 1 AND b LIKE 'abc%'→c仍可走索引(前缀匹配不破坏顺序) -
WHERE a = 1 AND b LIKE '%abc'→b索引失效(全模糊无法利用排序) -
WHERE YEAR(created_at) = 2023→ 即使created_at在索引最左,函数也导致失效
ORDER BY 和 GROUP BY 也受最左前缀约束
排序和分组想用上索引加速,列顺序和连续性要求和 WHERE 一样严格——因为它们依赖的是同一棵 B+ 树的物理顺序。
-
ORDER BY a, b, c→ 可用索引排序(完全匹配) -
ORDER BY a, c→c无法利用索引排序(跳过b) -
GROUP BY b, c→ 无法用(a, b, c)索引加速(没a) -
SELECT a, b FROM t WHERE a = 1→ 若(a, b)是索引,这就是覆盖索引,无需回表
真正容易被忽略的点是:索引列顺序不是凭感觉排的。a 是高频等值查询字段,b 是范围条件,c 是排序字段?那就得把 a 放最左,b 居中,c 放右——顺序一错,整条索引可能只发挥 30% 的作用。











