智汇 IT
城启新篇

数据库慢查询定位与优化别急着重启先看这几处

凌晨两点的转圈 不是重启能救的

订单列表接口 p99 从 120ms 飙到 8s。客服群里炸锅。值班同学第一反应:重启数据库?别。重启像退烧药,热度下去半小时,又烧。先保留现场。看监控,看连接数,看慢查询日志。说实话,很多人只盯 CPU,忽略 QPS 突增和锁等待。这两样一个在明一个在暗,暗的那个更疼。

MySQL慢查询日志分析终端截图
MySQL慢查询日志分析终端截图

慢查询日志开了没?long_query_time 设多少?采样阈值太粗,1s 才记,可业务 300ms 就超时。太细,日志写爆磁盘。经验:核心接口 SLA 的 1/5 到 1/3 当阈值。别照搬。还有 log_queries_not_using_indexes 别随便开,小表全扫也记,淹死你。

EXPLAIN 别只看 type 那一列

找到 SQL 后,EXPLAIN。但别只看 type=ALL。要看 rows、filtered、Extra。Using filesort 和 Using temporary 同时出现,基本要炸。有一次,一个看似简单的 where status=1 order by create_time limit 20,走错索引,扫了 400 万行。为什么?status 区分度太低,优化器觉得全表更快。加联合索引 (status, create_time) 后,rows 从 400 万降到 20。爽。

MySQL执行计划EXPLAIN分析界面
MySQL执行计划EXPLAIN分析界面

但也要注意边界。联合索引不是银弹。范围查询后面的列会失效。order by 和 where 混用,最左前缀可能断掉。看执行计划时,把 SQL 里的变量换成真实值,别用 ? 占位符。优化器会按实际值估算。还有,EXPLAIN ANALYZE 能看真实耗时,MySQL 8.0 以上值得开。注意它真跑 SQL,生产上别乱来。

索引加得爽 写放大哭得响

有些团队一出慢查询就加索引。加完读快了,写入慢了。订单表一天 500 万写入,你加五个二级索引,每个 insert 都要维护。磁盘 IO 和 redo 扛不住。索引像调料。少了没味,多了齁。

更隐蔽的是冗余索引。已经有 (a,b,c),再来 (a,b)。浪费空间,拖慢写入。定期用 sys.schema_redundant_indexes 查。或者 pt-duplicate-key-checker。别问我怎么知道,血泪。

数据库B树索引结构图
数据库B树索引结构图

锁和连接池 经常背锅但真有问题

锁和连接池 经常背锅但真有问题
锁和连接池 经常背锅但真有问题

慢查询不一定是查询慢。可能是等锁。InnoDB 行锁,等 metadata lock,等 flush。看 SHOW ENGINE INNODB STATUS,看 sys.innodb_lock_waits。一个未提交事务挂着,后面全排队。还有连接池。HikariCP 最大池 20,数据库 max_connections 100,应用实例 10 个。一算就知道超。连接被占满,新请求在池外排队。日志里全是 timeout。

怎么破?先 kill 掉阻塞源头,再考虑限流。线上止血,不是炫技。ALTER TABLE 加索引?大表别直接干。用 gh-ost 或 pt-online-schema-change。业务低峰期。准备好回滚。

一条能落地的排查清单

1. 先看应用侧耗时分布。是 DB 慢,还是网络、序列化、下游。
2. 打开慢查询日志,设合理阈值,收集 10 分钟。
3. 按 执行次数 × 单次耗时 排序,别只看单次最慢。
4. EXPLAIN 看 rows、filtered、Extra,关注临时表和文件排序。
5. 查锁等待和连接池活跃数。
6. 能加索引就加,但评估写入影响。
7. 改不了 SQL 就改业务:分页、缓存、异步、限流。

说白了,数据库慢查询定位与优化不是 DBA 一个人的活。开发要知道索引怎么走,运维要知道连接池多大,产品要知道哪些查询能砍。团队一起看,比一个人瞎猜快得多。别怕慢,怕的是没数据瞎调。先记录,再假设,再验证。很多时候,答案就在那条被忽略的慢日志里。

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:数据库慢查询定位与优化别急着重启先看这几处
文章链接:https://www.itcdj.com/news/832.html