← 每日面试题 学习看板

a,b两个单独索引,where a=xx and b=xx 走哪个索引?为什么?

面试题/03数据库中间件/01MySQL/03索引设计与优化(核心面试点)/a,b两个单独索引,where a=xx and b=xx 走哪个索引?为什么?.md

面试记录 2026-10-13

题目:a,b两个单独索引,where a=xx and b=xx 走哪个索引?为什么?

难度:medium

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

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

我的回答

具体装哪个索引不一定,MySQL 会根据索引的具体区分度以及使用索引的成本来规划优化选择哪个索引去使用。

但是如果这么一个搜索条件的话,并且经常使用,推荐建 A 跟 B 的联合索引,让两个字段都能被使用到,提升效率。

这两个字段 A 跟 B,看优化器选择,哪个区分度高,筛选的成本更少,能取到更少,能在更少的数据集中找到目标结果。一般优化器会选择对应的索引,并不会根据直接查看就会知道使用哪个索引。但是如果使用联合索引,将两个数据字段都使用上,这样就可以保证更好的优化,更少的数据集被选择。

点评

优点:

不足:

补充:

  1. 估算每个候选方案的扫描行数和回表行数
  2. 计算总成本(IO + CPU)
  3. 选成本最低的方案;如果都太高就选全表扫描

完整讲解

第一部分:知识重点剖析

核心考点定位:理解 MySQL 优化器的成本模型、掌握 EXPLAIN 关键字段、能给出合理的索引优化方案。

知识点拆解:

  1. MySQL 是成本模型优化器(Cost-based Optimizer)
  1. 单列索引 a、b 各自的成本估算
  1. Index Merge(索引合并,MySQL 5.6+)
  1. 为什么联合索引 (a, b) 通常是最好的
  1. 优化器可能放弃索引走全表
  1. 优化器选错索引的常见原因与解决
  1. EXPLAIN 关键字段速查

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

考察方向:

延伸递进面试题:

  1. 为什么 Index Merge 很少被优化器选中?
  1. 优化器选错索引怎么排查?
  1. 联合索引 (a, b) 和 (b, a) 有什么区别?

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

面试官您好,这个问题我按"优化器怎么选 + 为什么这样设计"来答。

先说优化器怎么选。MySQL 是成本模型优化器,它会枚举所有候选方案——走索引 a、走索引 b、走 Index Merge、走全表扫描——然后估算每个方案的成本,选最低的。成本模型的核心是回表次数:走哪个索引,回表过滤另一列的次数最少,优化器就选哪个。所以两个索引区分度差得多时,优化器会选区分度高、扫描行数少的那个;区分度差不多时可能选谁都不一定,具体要看统计信息和当前负载。

Index Merge 是一种理论上的方案,5.6+ 支持。对 WHERE a=xx AND b=xx 优化器可以考虑走两个单列索引分别扫描再取交集(Using intersect)。但实际很少被选中——需要扫两个索引 + 合并结果集,成本通常远高于单个联合索引。除非两个索引都是覆盖索引才可能划算。

推荐建 (a, b) 联合索引是标准答案。因为联合索引一次扫描就能同时定位 a 和 b,理想情况命中就 1 行,回表 1 次;相比之下走单索引最坏要回表成千上万行过滤另一列。频繁一起查的字段一定要建联合索引,这是最本质的优化。

优化器可能完全放弃索引走全表。如果两个索引区分度都低(比如 WHERE gender='M' AND status=1,两个字段各自筛出 40%),扫描占比超过 30% 时优化器会倾向全表扫描,因为 B+ 树随机 IO 不如顺序扫描快。EXPLAIN 显示 key=None type=ALL 就是这种情况。

排查线上优化器选错索引我会按这个流程:先看 EXPLAIN 的 rows 和 filtered 判断是不是选错了;跑 ANALYZE TABLE 刷新统计信息看有没有变化;如果还是选错,FORCE INDEX 强制走指定索引验证效果。FORCE INDEX 生产慎用——索引被删或改结构 SQL 直接生产报错。8.0 的优化器成本模型比 5.7 精准很多,能少踩坑。

当然,具体走哪个索引不能只看索引就断言,一定要用 EXPLAIN 验证。EXPLAIN 里 key 是实际选择的索引、rows 是预估扫描行数、Extra 里的 Using index 说明是覆盖索引、Using filesort 说明需要额外排序——这几个字段基本能定位大部分优化器决策问题。