定位sql性能瓶颈关键在排查顺序:先确认是否数据库问题,排除应用层、网络、缓存等干扰;再结合慢日志、应用日志、监控指标定位真凶;最后用explain分析执行计划,关注type、rows、extra及数据规模、并发、索引覆盖。

定位SQL性能瓶颈,关键不在“查哪条SQL”,而在“按什么顺序查”。思路乱了,花再多时间看执行计划也容易南辕北辙。
先确认是不是数据库的问题
很多“慢接口”根本不是SQL导致的。要先排除应用层、网络、缓存、下游服务等因素:
- 查接口整体耗时分布:是P95突增,还是均值缓慢上升?
- 比对同一接口在不同环境(测试/预发/生产)的表现,快速缩小范围
- 看调用频次——单次20ms的SQL,若被循环调用300次,总耗时就达6秒
- 检查是否有锁等待:
SHOW PROCESSLIST里出现大量Waiting for table metadata lock或Locked状态
从日志和监控里揪出真凶
别靠猜,用数据说话。线上最可靠的线索来自三类记录:
-
慢查询日志:MySQL开启
slow_query_log,阈值建议设为0.5~1秒;用mysqldumpslow -s t -t 10提取最耗时的前10条 - 应用日志:尤其关注ORM框架(如MyBatis、Hibernate)打印出的SQL及耗时,注意是否含隐式N+1查询
- 数据库监控指标:观察QPS陡升、InnoDB行锁等待次数、Buffer Pool命中率骤降等异常信号
执行计划是核心判断依据
拿到可疑SQL后,第一件事就是EXPLAIN(MySQL)或EXPLAIN ANALYZE(PostgreSQL)。重点关注三项:
-
type字段:出现
ALL说明全表扫描,大表上基本等于性能红灯 - rows字段:预估扫描行数远大于实际返回行数,大概率索引没生效或选择性差
-
Extra字段:含
Using filesort或Using temporary,意味着排序/分组未走索引,可能触发磁盘临时表
别忽略数据规模和并发影响
同一条SQL在10万行和1000万行表现天壤之别。优化前必须明确:
- 当前表数据量、主键增长趋势、历史归档策略
- 该SQL是否在高峰期集中执行?是否存在高并发写入导致读被阻塞?
- 索引是否覆盖了WHERE + ORDER BY + SELECT字段?联合索引字段顺序是否匹配查询条件顺序?
思路清晰了,定位就快了一半。真正的瓶颈往往藏在“接口→SQL→执行计划→数据特征”这条链路里,而不是某一行代码上。











