JJava 知识库
JAVA INTERVIEW

高频面试题

MySQL进阶约 3 分钟

一条 SQL 昨天还很快,今天突然变慢,你会怎么用 EXPLAIN ANALYZE 找到真正耗时的位置?

参考回答约 3 分钟 · 口语表达
先说结论

我会先控制影响,再按证据定位:从连接、解析、优化、执行到 EXPLAIN ANALYZE 系统定位慢 SQL

01

我会先确认影响范围,同时控制故障继续放大。从连接、解析、优化、执行到 EXPLAIN ANALYZE 系统定位慢 SQL。

02

止损之后,我会按请求链路建立证据,而不是凭经验猜。客户端先通过连接器建立会话,完成认证并获得权限。连接建立后,会话拥有独立的事务状态、字符集、系统变量和临时表等上下文。生产中应通过连接池复用连接,但连接池上限不能超过数据库实际承载能力。 SQL 进入 Server 层后,解析器完成词法和语法分析,构建内部语法结构。随后预处理阶段解析表和列、检查歧义与权限。优化器依据统计信息、索引、连接顺序和成本模型生成执行计划,执行器再调用 InnoDB 等存储引擎接口读取或修改数据。 sql/joinoptimizer:连接顺序和成本选择。 EXPLAIN ANALYZE FORMAT=TREE:估算与实际逐节点对比。 我会先确认请求实际走到了哪条路径,再用运行数据验证,不会只看类名或配置猜测。

03

定位时我最关注这些参数、指标和容量关系。用常见值与极端偏斜参数分别执行,比较 estimated rows/actual rows 与 chosen plan。

04

找到根因后先做最小修复,再用同样的流量验证。优化器高估过滤选择性,选择新索引后回表数十万次;全表顺序扫描原本更便宜。更新统计、增加覆盖列并用 EXPLAIN ANALYZE 核对估算与实际后,计划才稳定。 只看 type 不看实际扫描行数:估算与实际行数偏差:更新统计/直方图。 把 Using filesort 一律视为错误:rows examined/returned:减少读取列与行。 固定输入和基线 先在没有故障注入的环境执行上述配置,固定数据规模、并发度、运行时版本和预热时间。以「估算偏差」为主基线,记录值应满足「<10倍示例」;同时保存 估算与实际行数偏差、rows examined/returned,使后续变化能够回到同一时间轴比较。

05

恢复阶段要逐步放量,最后把监控和边界补齐。方案:更适合的场景:主要收益:代价与边界。 普通 EXPLAIN:上线前查看计划结构:安全快速:只有估算没有真实耗时。 EXPLAIN ANALYZE:测试环境或可控查询:实际行数和节点时间清晰:会真正执行,写语句和慢查询需谨慎。 Optimizer Trace:计划选择原因难理解:展示候选成本与裁剪:输出复杂且有运行开销。 选型至少带上 数据规模、选择性、读写比、事务长度和峰值并发,并用上面的量化基线验证;

排查与恢复时间线从目标到落地
01解析与权限检查
02优化器枚举访问路径
03依据统计信息估算成本
04执行器拉取并连接记录
05EXPLAIN ANALYZE 对比估算与实际