VPS上的MySQL突然变慢,不应一开始就增加内存或修改大量参数。先确认慢的是单条SQL、某类请求,还是整个服务器;随后在受控时间窗采集慢查询、锁等待和系统资源证据。慢查询日志能告诉你“哪些语句超过阈值”,EXPLAIN帮助判断执行计划,但两者都不能脱离CPU、内存、磁盘和业务并发单独解释。
先判断数据库慢在哪一层
| 症状 | 更可能的方向 | 先查什么 |
|---|---|---|
| 所有查询同时变慢 | CPU、磁盘I/O、内存回收或连接拥塞 | top、vmstat、iostat、连接数 |
| 某个接口或报表慢 | SQL扫描、排序、临时表或索引问题 | 慢查询样本与EXPLAIN |
| 写入期间读写一起卡住 | 锁等待、长事务或热点行 | 当前事务和锁等待 |
| 流量不高却周期性变慢 | 备份、日志轮转、定时任务或检查点 | 时间轴与系统任务 |
| 连接建立慢或报满 | 连接池、DNS、认证或连接上限 | 连接状态与应用池配置 |
记录准确时间和时区很重要。数据库日志、应用日志和VPS监控只有放在同一时间轴,才能判断因果顺序。
先查看当前慢查询配置
在有管理权限且了解影响范围的前提下,可先只读查询:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'log_queries_not_using_indexes';long_query_time决定超过多长时间才记录。没有适用于所有数据库的固定阈值:在线接口、报表和批处理对延迟的要求不同。阈值过高会漏掉有业务影响的查询,过低则可能制造大量日志和额外I/O。
log_queries_not_using_indexes也不应长期盲目开启。小表全扫可能很快,开启后日志量可能激增;是否记录应结合短时诊断目标。
怎样短时开启慢查询日志
生产环境修改前先确认MySQL或兼容发行版的版本、配置文件位置、磁盘余量和变更回滚。可在维护流程中使用运行时变量进行短时观察:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;上面的1秒只是演示值,不是推荐阈值。运行时设置可能在重启后失效;写入配置文件则会持久生效,语法和文件位置取决于当前发行版。诊断完成后应恢复原设置,并确认日志文件权限、轮转和磁盘占用。
不要把包含密码、个人数据或业务敏感参数的完整SQL直接发布。导出样本前应脱敏,并限制访问权限。
从慢日志里挑出真正值得查的SQL
不要只按单次最慢排序。至少记录:
- 执行次数和总耗时;
- 单次执行时间与分布;
- 检查行数和返回行数;
- 锁等待时间;
- 发生时间、数据库和调用接口;
- SQL是否只是参数不同的同一模板。
一条偶发的报表查询可能单次很慢,但高频中等慢查询的总资源消耗更大。应先按SQL模板聚合,再结合业务重要性排序。使用日志分析工具前核对其版本和脱敏方式,不要把生产日志上传到未知服务。
用EXPLAIN检查执行计划
对经过脱敏、可安全复现的SELECT查询,可在测试环境或低风险时间窗使用:
EXPLAIN SELECT ...;重点观察访问类型、可能使用的索引、实际选中的索引、预计扫描行数,以及是否出现额外排序或临时表等信息。字段名称和输出能力会随MySQL版本变化。
EXPLAIN展示的是优化器计划,不等于完整运行时事实。部分版本支持更深入的执行分析,但可能真正运行查询;在生产环境使用前必须确认副作用和负载,尤其不能对写语句或高成本查询盲目执行。
没有使用索引就一定要加索引吗
不一定。小表全扫可能比走索引更快,低选择性列的单列索引也可能帮助有限。新增索引会增加磁盘空间、写入成本和维护开销。
判断前先核对:
- WHERE、JOIN、ORDER BY和GROUP BY实际使用哪些列;
- 联合索引的列顺序是否匹配主要查询;
- 条件是否对索引列做了函数或隐式类型转换;
- 返回数据是否过多,应用是否本可分页或缩小字段;
- 统计信息是否过时,数据分布是否已经变化。
索引调整应先在接近生产数据分布的环境验证,并准备回退。不要在高峰期直接为大表建立索引。
别漏掉锁等待和长事务
SQL本身执行计划正常,也可能因为等待其他事务而变慢。应结合当前MySQL版本支持的系统视图查看运行中的事务、锁等待和连接状态。重点找持续时间异常的事务、未提交连接和批量写入。
不要为了“解除卡顿”直接批量终止连接。先确认事务用途和回滚成本;大型事务被终止后,回滚过程本身也可能持续占用I/O和锁。
把数据库证据和VPS资源放到一起
vmstat 1 5
iostat -xz 1 5
free -h
慢查询发生时,如果磁盘等待和队列同步上升,应查日志、临时表、排序、备份与云盘延迟;如果CPU运行队列高,检查高频SQL和并发;如果available持续低、换页活跃,则要核对数据库缓冲池与其他进程的共同工作集。
单纯把缓冲池、连接上限或缓存参数调大,可能把压力转移到内存或让并发争用更严重。参数调整应基于当前版本、数据规模和采样证据。
修复后怎样证明真正变快
- 保留修改前的SQL模板、执行计划、执行时间分布和系统资源。
- 在测试环境或受控窗口修改SQL、索引或应用调用方式。
- 使用相同参数范围和接近的数据分布复测。
- 观察接口延迟、扫描行数、锁等待、CPU和磁盘I/O是否同时改善。
- 持续观察一个完整业务周期,确认没有写入放大和新回归。
只看一次EXPLAIN或一次查询变快不够。缓存冷热、并发和数据分布都会影响结果,必须使用同口径对照。
结论
VPS上的MySQL变慢,应先按整机资源、锁等待和SQL执行计划三条线分层。用短时慢查询日志找样本,用EXPLAIN判断扫描与索引,再把结果与VPS的CPU、内存和I/O对齐。任何索引或参数修改都应经过可回退的验证,而不是凭单条日志直接上线。






