← 每日面试题 学习看板

MySQL索引一定遵循最左前缀匹配吗?

面试题/03数据库中间件/01MySQL/03索引设计与优化(核心面试点)/MySQL索引一定遵循最左前缀匹配吗?.md

面试记录 2026-10-13

题目:MySQL索引一定遵循最左前缀匹配吗?

难度:medium

标签:db/mysql/index, mysql/index, difficulty/medium

评分:⭐⭐⭐⭐☆(4/5)

我的回答

这个前缀匹配是 MySQL 基础的索引中使用的基础规则,但并不是一定遵守,因为它还有包括全文索引、位图索引,还有其他的索引方式。

比如全文索引,它创建的索引就是对于索引字段进行分词,然后比对,和最左前缀没什么关系。

最左前缀只是指包括联合索引和普通的索引中使用的索引规则。其实主要是联合索引,普通索引直接比对字段了,和最左前缀没什么关系。然后 Like 的时候使用的也类似于最左前缀,因为它比对是从左往右。如果是中间或者是右侧区域 Like,在左侧 Like 的时候,使用模糊匹配,它是不能走索引的,这也是最左前缀的一个体现。

全文索引就不是这样了

点评

优点:

不足:

补充:

  1. Skip Scan(8.0):低基数首列跳跃扫描,Extra=Using index condition
  2. Index Merge:OR 条件多索引合并,Extra=Using union(...)
  3. ICP:索引条件下推,Extra=Using index condition
  4. Functional Index(8.0):表达式建索引
  5. 优化器回退:满足最左前缀但代价过高也会选全表

完整讲解

第一部分:知识重点剖析

核心考点定位:理解最左前缀规则的底层原因(B+ 树有序性),以及 MySQL 8.0 引入的多个"绕开"机制。

知识点拆解:

  1. 最左前缀规则的底层原因
  1. 最左前缀规则被打破的场景(5 类)
  1. LIKE 与最左前缀的关系
  1. ICP(Index Condition Pushdown)—— MySQL 5.6+
  1. 优化器成本模型(Cost-based Optimizer)
  1. Hash 索引的特殊性

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. Skip Scan 跳跃扫描在什么条件下生效?如何验证?
  1. (a, b, c) 索引,WHERE a=1 AND c=3 会不会因为 c 不满足最左前缀而全表扫描?
  1. 如果优化器放弃索引走全表,怎么强制走索引?有哪些风险?

第三部分:面试者参考回答(口语化)

面试官您好,最左前缀不是一定遵守的,我按"底层原理 + 绕开机制"两层来讲。

底层原理:最左前缀本质是 B+ 树的有序性决定的。(a, b, c) 联合索引在 B+ 树里是先按 a 排,a 相同再按 b 排,所以必须先固定前面的列才能利用后面的列的有序区间定位。跳过中间列 → 后面的列在这个前缀下无序 → 索引用不上。这个规则只适用于 B+ 树类索引,所以索引类型本身就会打破它。

能绕开最左前缀的机制,MySQL 8.0 已经比较多了。第一是 Skip Scan 跳跃扫描,8.0 新特性,当首列基数很低(比如性别只有两个值),且查询在后列也能精确匹配时,优化器会跳过首列做一次遍历合并结果——WHERE city='Beijing' 在 (gender, city) 索引上就能跳过 gender 直接扫 city。第二是 Index Merge,WHERE a=1 OR b=2 走两个单列索引再 UNION,绕开单个联合索引。第三是 Functional Index,8.0 可以建表达式索引,INDEX((lower(name))) 让 WHERE lower(name)='x' 也能走。第四是其他索引类型,比如全文索引是倒排结构、Hash 索引是哈希定位,跟 B+ 树最左前缀规则完全无关。第五是优化器成本模型——即使满足最左前缀,如果估算扫描行数占比太高,优化器也可能直接放弃走全表。

再补充一个容易被误会的点:ICP(索引条件下推)不是绕开最左前缀,而是让"看起来用不上最左前缀"的列也在索引层过滤。(a, b, c) 索引上 WHERE a=1 AND c=3,c 虽然不在最左前缀上,但通过 ICP 下推到存储引擎层过滤,能显著减少回表次数。

至于优化器放弃索引的场景,MySQL 5.7 可以 FORCE INDEX 强制走,但生产环境慎用——索引被删或改结构 SQL 直接生产报错,而且统计信息变化后可能反而比全表慢。实际线上更推荐通过调整索引设计让优化器自动选对,而不是硬干预。

当然,最左前缀这个规则在 8.0 里被大量优化器机制"松绑"了,理解它的关键还是回到 B+ 树的有序性——只要索引结构是 B+ 树,规则本质成立;只要索引结构不是 B+ 树,或者优化器判断 B+ 树扫描代价过高,规则就会被打破。