MySQL 索引和慢查询是后端面试高频题,但很多回答会停在“B+ 树、最左前缀、覆盖索引”。这些概念要会,不过项目面里更重要的是:你遇到一个接口慢,怎么判断是不是数据库慢?如果是数据库慢,怎么一步步证明问题在哪里?
面试官真正想听的是排查过程,而不是索引名词堆叠。一个慢查询背后可能是索引不合适,也可能是返回数据太多、排序分页太重、锁等待、连接池耗尽,甚至是上游重复调用。
先证明慢在数据库
接口慢时,不要一上来就说加索引。先看链路耗时:网关、应用处理、数据库查询、下游调用分别花了多久。如果链路追踪或日志显示数据库查询占主要耗时,再进入 SQL 分析。
这一步很重要。很多候选人会把所有慢都归因于数据库,但真实项目里,慢可能出在远程接口、序列化、锁竞争、线程池排队。能先定位位置,说明你有工程排查意识。
再看 SQL 形态
分析 SQL 时,先看查询条件、排序、分页、返回字段和数据量。比如一个列表接口同时按用户、状态和时间筛选,还要按创建时间倒序,如果索引只建在状态字段上,通常效果不会好。状态字段区分度低,扫描的数据仍然可能很多。
联合索引要围绕高频查询路径设计。不是字段越多越好,也不是哪个字段出现就加哪个字段。要看过滤条件是否稳定,排序能否利用索引,返回字段是否可以减少回表,分页是否会越翻越慢。
Explain 要读出信号
Explain 不是仪式感。看执行计划时,候选索引和实际索引能告诉你数据库有没有用到预期索引;rows 能估算扫描范围是否过大;Extra 里的额外排序、临时表、索引条件下推等信息,能提示查询代价在哪里;key_len 可以辅助判断联合索引到底用到了几列。
但也不要把 Explain 神化。执行计划只是静态估算,线上慢还要结合慢日志、真实参数、数据分布和锁等待。一个测试环境很快的 SQL,在线上大数据量和不同参数下可能完全不一样。
索引优化要考虑写入代价
索引不是越多越好。每个索引都会占空间,也会增加写入和更新成本。如果为了一个低频后台筛选建了很多索引,可能影响核心写入链路。更成熟的做法是区分核心接口和低频查询:核心路径优先优化,低频复杂查询可以走离线报表、搜索系统或限制条件。
如果面试官追问“为什么这个字段放在联合索引前面”,不要只背最左前缀。要结合查询频率、等值条件、范围条件、排序需求和字段区分度说明。这样回答更接近真实设计。
面试里可以这样收束
一个完整回答可以是:我会先用链路耗时证明慢在数据库,再看 SQL 的查询条件、排序分页和返回字段;接着用慢日志和 Explain 验证扫描行数、索引命中和额外排序;优化时会考虑联合索引、覆盖索引、分页方式和数据量,同时评估索引对写入的影响。这样讲,数据库题就不只是背概念,而是一次可以落地的排查。