MySQL慢SQL排查实战:从定位到EXPLAIN优化闭环

发布时间:2026/6/2 0:58:40

MySQL慢SQL排查实战:从定位到EXPLAIN优化闭环 线上接口突然变慢时最忌讳直接猜 SQL 哪里不对。一个更稳的排查方式是先定位慢请求再定位慢 SQL再用执行计划看数据库为什么慢最后围绕索引、返回字段、表设计和架构做优化。这篇文章把慢 SQL 排查拆成一条闭环监控发现问题 - 慢查询日志定位 SQL - EXPLAIN 分析原因 - 针对性优化 - 再验证效果。如果把排查动作画成一条线大概是这样1. 先判断慢在哪里接口慢不一定是数据库慢。一次请求可能慢在网关、应用代码、远程调用、缓存、消息队列也可能慢在数据库。排查时可以先用链路追踪或监控工具确定瓶颈位置。常见工具可以分成两类类型工具适合做什么应用调试Arthas在线观察方法耗时、线程、调用栈链路监控SkyWalking看接口链路、服务调用、慢方法和慢 SQL指标监控Prometheus观察 QPS、响应时间、连接数、资源指标数据库日志MySQL 慢查询日志记录超过阈值的 SQL如果链路追踪显示某个接口耗时主要集中在数据库访问就可以进入 SQL 层面继续查。2. 开启慢查询日志MySQL 自带慢查询日志可以记录执行时间超过long_query_time的 SQL。调试环境或压测环境中可以把阈值设置得短一些例如 2 秒方便快速暴露问题。slow_query_log1long_query_time2配置后重启 MySQL再观察慢查询日志文件。常见位置类似/var/lib/mysql/localhost-slow.log慢查询日志能回答两个问题哪些 SQL 慢以及慢到了什么程度。但它还不能直接告诉你为什么慢。下一步需要用EXPLAIN。3. 用 EXPLAIN 看执行计划EXPLAIN或DESC可以查看 MySQL 准备如何执行一条SELECT语句。EXPLAINSELECTid,name,statusFROMtb_userWHEREnameTomANDstatus1;执行计划里最常看的字段有四个字段重点看什么常见判断possible_keys可能使用哪些索引如果为空通常说明可用索引不足key实际使用哪个索引有索引不代表一定会被优化器选择key_len使用了索引的多少字节联合索引中可辅助判断用到了几列type访问类型越靠近 const 越好all 往往需要重点优化Extra额外信息关注 Using filesort、Using temporary、是否能覆盖索引看执行计划时不要只盯一个字段。更实用的顺序是先看有没有索引再看扫描方式最后看额外成本3.1 type 字段怎么看type可以理解为 MySQL 找数据的方式。一般来说性能从好到差大致如下NULL system const eq_ref ref range index alltype含义优化关注点const通过主键或唯一索引命中一条记录通常很好eq_ref连接时使用主键或唯一索引通常很好ref使用普通索引匹配常见且可接受range范围扫描注意范围右侧联合索引可能失效index扫描整棵索引树比全表扫描好但仍可能很重all全表扫描大表上通常需要重点处理看到all不要立刻只想着加索引还要结合返回字段、过滤条件、数据分布和排序分组方式一起看。4. 慢 SQL 常见原因慢 SQL 的原因通常集中在这几类查询条件没有合适索引导致全表扫描。建了索引但写法不对导致索引失效。返回字段太多触发大量回表尤其是select *。多表关联顺序不合理大表驱动小表。排序、分组、去重产生临时表或额外排序。数据量过大普通分页越翻越慢。表字段设计不合理导致存储和比较成本过高。5. SQL 优化可以从哪里下手优化不要只盯着单条 SQL。更完整的思路应该包括表结构、SQL 写法、索引、连接方式和架构。5.1 表设计优化字段类型越合适存储和比较成本越低。能用tinyint就不要随手用bigint能明确长度就不要无限放大。字符串字段也要区分char和varchar类型特点适合场景char定长空间可能浪费但比较稳定固定长度编码、状态码varchar变长空间更灵活用户名、标题、地址等5.2 查询字段优化尽量避免SELECT*FROMtb_userWHEREnameTom;更推荐明确字段SELECTid,name,statusFROMtb_userWHEREnameTom;这样不仅减少网络传输也更容易利用覆盖索引避免回表。5.3 避免索引失效写法典型写法包括在索引列上做函数或表达式运算、字符串不加引号、like %keyword、联合索引不满足最左前缀法则等。索引失效时执行计划中的key、type、rows会给出明显信号。5.4 union all 优先于 unionunion会做去重通常需要额外排序或临时处理。如果业务允许重复优先使用SELECTidFROMt_userWHEREid2UNIONALLSELECTidFROMt_userWHEREid5;5.5 Join 关注驱动表多表关联时尽量让小结果集驱动大结果集。对于inner join优化器有机会调整顺序对于left join、right join连接方向会限制优化空间所以使用外连接时更要注意驱动表和索引。6. 面试回答模板可以这样组织回答我会先通过链路追踪或监控确认慢点是不是数据库访问。如果确认是 SQL 慢再看慢查询日志定位具体 SQL。拿到 SQL 后用EXPLAIN分析执行计划重点看type、key、key_len、rows、Extra。如果是全表扫描就检查查询条件和索引设计如果有回表就看能否用覆盖索引或减少返回字段如果有filesort或temporary就优化排序分组字段和联合索引如果是深分页就考虑覆盖索引加子查询或基于游标翻页。最后压测或对比执行计划验证优化是否真的生效。7. 小结慢 SQL 优化不是一句“加索引”就结束。更可靠的闭环是先用工具定位问题再用慢日志拿到 SQL再用EXPLAIN看执行路径最后根据具体原因处理。这样的回答既有排查顺序也能体现你真的理解数据库如何执行查询。

相关新闻