Skip to content

面试速答(先看这里)

**一句话结论:**不过需要注意,如果 b > 2 的选择性很差(即很多行符合条件),MySQL 可能仍需 filesort ;

60秒标准回答:

这是一个典型的索引相关的问题,这个问题其实不算难

这个SQL中可能和索引有关的内容有以下三个方面

综上所述,建索引肯定是有必要的

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**这是一个典型的索引相关的问题,这个问题其实不算难。
  • **要点2:**这个SQL中可能和索引有关的内容有以下三个方面:

**记忆锚点:**filesort → select → where → order → MySQL → and

易错提醒:

  • order by c,d,f : 排序字段是 (c, d, f) ,如果能被索引覆盖,就能避免 filesort 。
  • (c,d,f) 排序部分在某些情况下仍能部分利用索引顺序(取决于优化器和数据分布) 不过需要注意,如果 b > 2 的选择性很差(即很多行符合条件),MySQL 可能仍需 filesort ;

加分表达:

  • 建议建立如下索引: a 在最前面,因为是等值匹配;

追问准备:

  • 围绕「filesort」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「select」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「where」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

这是一个典型的索引相关的问题,这个问题其实不算难。

这个SQL中可能和索引有关的内容有以下三个方面:

  • where a = 1 and b >2:a = 1是等值匹配(高效),b > 2是范围匹配(次高效)。可以建立(a,b)联合索引,并且把a放前面。
  • order by c,d,f: 排序字段是 (c, d, f),如果能被索引覆盖,就能避免 filesort。 (因为索引天然有序)
  • select * : 查询所有字段,索引无法完全覆盖查询,仍需回表读取数据。

综上所述,建索引肯定是有必要的。

建议建立如下索引:

plain
CREATE INDEX idx_a_b_c_d_f ON table(a, b, c, d, f);
  • a 在最前面,因为是等值匹配;
  • b 在第二个位置,因为它是范围过滤;即使 b 是范围条件,MySQL 仍可利用 (a,b) 部分来过滤;
  • (c,d,f) 排序部分在某些情况下仍能部分利用索引顺序(取决于优化器和数据分布)

不过需要注意,如果 b > 2 的选择性很差(即很多行符合条件),MySQL 可能仍需 filesort;可以考虑不要b或者把他放到最后去。

plain
CREATE INDEX idx_a_c_d_f ON table(a, c, d, f, b);

CREATE INDEX idx_a_c_d_f ON table(a, c, d, f);