系统响应变慢的性能排查思路
从"能用"到"卡"通常有迹可循。本文给出一套从客户端到数据库的分层排查方法,以及最常见的五个性能瓶颈。
先确定范围
性能问题要先回答三个问题:
- 所有人都慢,还是个别人慢?
- 所有功能都慢,还是某个功能慢?
- 一直慢,还是某个时间段慢?
| 答案 | 方向 |
|---|---|
| 个别人慢 | 客户端、网络 |
| 所有功能慢 | 服务器、数据库 |
| 某功能慢 | 该功能的代码或查询 |
| 某时段慢 | 并发高峰、定时任务 |
分层排查
第一层:客户端
- 浏览器版本过旧
- 装了太多插件
- 电脑本身卡(内存不足、磁盘满)
- 终端设备老旧
快速验证:换一台电脑试。如果正常,问题在客户端。
第二层:网络
- 带宽被占满(有人在传大文件、看视频)
- 无线信号差
- 跨网络访问(比如通过公网访问内网系统)
快速验证:ping 目标服务器看延迟和丢包。
延迟超过 50ms 或丢包率超过 1%,就会明显影响体验。
第三层:应用服务器
- CPU 使用率高
- 内存不足,频繁 GC
- 磁盘 I/O 瓶颈
- 连接池耗尽
- 线程池耗尽
排查工具:系统监控(top、vmstat)、应用监控(APM)、日志分析。
第四层:数据库
这是最常见的瓶颈所在。
| 问题 | 表现 | 排查 |
|---|---|---|
| 慢查询 | 特定功能慢 | 慢查询日志 |
| 缺索引 | 数据量增长后变慢 | 执行计划 |
| 锁等待 | 并发时卡顿 | 锁监控 |
| 连接数满 | 新请求排队 | 连接池监控 |
| 表数据量过大 | 查询越来越慢 | 表大小统计 |
第五层:外部依赖
- 对接的第三方接口慢
- 文件存储慢
- 消息队列堆积
排查:看外部调用的耗时统计。
五个最常见的瓶颈
瓶颈一:缺索引
表现:数据量小的时候很快,数据量上来后越来越慢。
排查:看慢查询日志,对 WHERE、ORDER BY、JOIN 涉及的字段检查索引。
解决:加索引。但要注意:
- 索引不是越多越好(影响写入性能)
- 组合索引要考虑字段顺序
- 加索引前先评估对写入的影响
瓶颈二:全表扫描
表现:某条查询特别慢,几秒甚至几十秒。
排查:看执行计划是否有 full scan。
常见原因:
- 字段上用了函数(比如 WHERE DATE(create_time) = ...)
- 隐式类型转换(字符串字段传了数字)
- 模糊查询以 % 开头(LIKE '%xx')
解决:改写查询,让索引能生效。
瓶颈三:N+1 查询
表现:列表页面慢,且列表条数越多越慢。
原因:查主表 1 次,然后对每条记录再查子表 N 次。
解决:改为批量查询或关联查询。
瓶颈四:大表未分页
表现:报表、列表查询慢。
解决:
- 强制分页,不返回全量
- 分页时避免大偏移(LIMIT 100000, 20 这种)
- 用游标分页替代偏移分页
瓶颈五:定时任务与业务高峰重叠
表现:每天某个固定时间系统变慢。
原因:定时任务(报表统计、数据同步、备份)在业务高峰期执行,抢占了资源。
解决:把定时任务调整到业务低峰期(比如凌晨)。
排查的实用手段
1. 看监控曲线
CPU、内存、磁盘 I/O、数据库连接数的历史曲线,能快速定位异常时段。
2. 慢查询日志
开启慢查询日志(阈值设为 1 秒),定期分析。
3. 链路追踪
如果系统复杂,用链路追踪定位是哪个环节慢。
4. 压测
在测试环境模拟并发,复现问题。
注意:压测不要在生产环境做(除非有专门的预案)。
5. 二分法
如果是某次发版后变慢,用二分法定位是哪次改动引入的。
优化顺序建议
先改成本低的、效果大的。
- 加索引(成本低,见效快)
- 优化慢查询(中等成本)
- 调参数(连接池、缓存大小)
- 加缓存(Redis 等,对付读多写少的场景)
- 优化代码逻辑(成本高)
- 加机器 / 读写分离 / 分库分表(成本最高)
很多项目直接跳到第 6 步(加硬件),其实前面几步就能解决大部分问题。
预防措施
- 建库时就考虑索引,对高频查询字段提前建索引
- 定期检查慢查询,不要等到用户抱怨
- 数据量监控:单表超过千万行要预警
- 性能测试纳入上线流程:每次大版本发布前做一轮压测
- 建立性能基线:记录正常时的响应时间,用于对比
一个提醒
性能问题通常不是突然出现的,是逐渐累积的。
随着数据量增长、用户增加、功能叠加,系统会慢慢变慢。如果没有监控,等到用户抱怨时往往已经很严重了。
建议从上线第一天就建立监控和基线。
性能调优的具体手段与监控指标,[待补充:百华智造 MES 性能优化指南]。
这篇内容对你有帮助吗?
当前为游客态,投票按设备去重