主题切换
定位慢查询
一、什么是慢查询
1. 典型场景
- 聚合查询(比如大量数据的COUNT、SUM)
- 多表关联查询
- 大数据量表查询
- 深度分页查询(比如
LIMIT 100000, 10)
2. 表象特征
页面加载慢、接口压测响应时间超过1秒,大概率存在慢查询问题。
二、定位慢查询的两种方案
方案一:开源工具定位
- 调试工具:Arthas(可以在线上动态查看方法执行耗时)
- 运维/APM工具:Prometheus、Skywalking
- 比如Skywalking可以直观看到每个接口的响应耗时,直接定位到耗时最高的接口,再进一步排查是不是SQL导致的问题。
方案二:MySQL自带慢查询日志
- 原理:记录执行时间超过指定阈值(
long_query_time,默认10秒)的SQL语句。 - 开启方式:在MySQL配置文件
/etc/my.cnf中添加配置:inislow_query_log=1 long_query_time=2 - 查看日志:日志文件默认路径
/var/lib/mysql/localhost-slow.log,里面会记录SQL执行时间、锁等待时间、扫描行数等关键信息。
三、实际排查流程(面试/项目场景)
- 先描述场景:接口压测响应时间高达5秒,明显异常。
- 用运维工具(Skywalking)定位到具体接口,确认瓶颈在SQL执行环节。
- 开启MySQL慢查询日志,设置阈值为2秒,捕获超时SQL语句。
面试相关问题
问:Skywalking这类运维工具属于中间件吗? 答:不算。中间件是为应用提供通用底层服务的组件(比如缓存、消息队列),而Skywalking是APM监控工具,核心是采集、分析系统运行状态,属于可观测性工具,和业务中间件的定位不同。
问:线上环境为什么不建议一直开启慢查询日志? 答:一是日志写入会带来额外的IO开销,高并发场景下可能影响数据库性能;二是日志文件会持续增大,占用磁盘空间,所以一般只在排查问题时临时开启,调优完成后关闭。
问:除了慢查询日志和APM工具,还有其他定位慢查询的方法吗? 答:可以用
show processlist查看当前正在执行的SQL,或者用explain直接分析疑似慢SQL的执行计划,判断是否存在索引失效、全表扫描等问题。问:
long_query_time的阈值设置成多少合适? 答:线上调试一般设为1-2秒,默认的10秒太晚了,很多业务场景超过1秒就已经影响用户体验了;但也不能设得太低,否则会产生大量日志,反而不利于排查问题。问:慢查询日志里的
Query_time和Lock_time有什么区别? 答:Query_time是SQL实际执行的时间,Lock_time是SQL等待锁释放的时间。如果Lock_time很高,说明不是SQL本身执行慢,而是锁冲突导致的等待时间过长,需要排查锁竞争问题。