数据库慢查询分析优化性能:从零开始的排查指南
为什么数据库会变慢?先找到“罪魁祸首”
很多新手站长遇到过这种情况:网站突然变卡、页面加载超时,甚至服务器CPU飙升。
这往往是因为数据库中存在慢查询——执行时间超过预设阈值的SQL语句。
要解决这个问题,核心思路就是:开启慢查询日志 → 收集慢SQL → 分析执行计划 → 针对性优化。
下面从零开始,一步步带你在Linux服务器(以CentOS 7 + MySQL 5.7为例)上完成整个过程。
前置准备:检查当前配置并开启慢查询日志
登录服务器后,先用SSH连接,运行以下命令登录MySQL:
mysql -u root -p
输入密码后,依次执行两条查询,确认当前慢查询日志的状态:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
如果 slow_query_log 值为 OFF,则需要开启。
MySQL默认的慢查询时间阈值是10秒,对大多数网站来说太宽松了,建议改为2秒或1秒。
用以下命令临时开启(重启MySQL后失效):
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2;
如果想永久生效,需要修改MySQL配置文件(通常位于 /etc/my.cnf 或 /etc/mysql/my.cnf):
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2
保存后重启MySQL服务:
systemctl restart mysqld
核心操作:分析慢查询日志并找到问题SQL
配置完成后,过一段时间(比如一天),去查看慢查询日志的路径。
使用 mysqldumpslow 工具可以快速统计出最耗时的SQL。
mysqldumpslow -s t -t 5 /var/log/mysql/mysql-slow.log
这条命令会按查询时间(-s t)排序,显示前5条最慢的SQL。
结果示例:
Count: 1 Time=8.00s (8s) Lock=0.00s (0s) Rows=100000.0 (100000)
SELECT * FROM orders WHERE status = 'pending' AND create_time < '2023-01-01';
找到疑似慢SQL后,我们需要用 EXPLAIN 分析它的执行计划,看是否走了全表扫描。
在MySQL中执行:
EXPLAIN SELECT * FROM orders WHERE status = 'pending' AND create_time < '2023-01-01'\G
重点关注 type 字段:如果是 ALL,说明是全表扫描,必须优化;如果是 index 或 range,说明用了索引,但还可以进一步优化。
rows 字段估算扫描的行数,如果远大于实际返回的行数,说明索引不够有效。
Extra 中出现 Using filesort 或 Using temporary,代表查询需要排序或临时表,也需要注意。
避坑指南:常见错误操作与正确姿势
1. 索引不是越多越好。 给每个字段都加索引会导致写入变慢、占用磁盘空间。
建议只给 WHERE、JOIN、ORDER BY 中频繁出现的字段加索引。
2. 不要在索引列上做函数操作。 例如 WHERE DATE(create_time) = '2023-01-01' 会导致索引失效,
应改为 WHERE create_time >= '2023-01-01' AND create_time < '2023-01-02'。
3. 避免使用 SELECT *。 只查询需要的列,减少数据传输和临时表。
4. 小表也要留意。 即使表只有几千行,如果查询频繁且不走索引,也可能成为瓶颈。
5. 慢查询日志文件会不断增大,记得定时清空或轮转。 可以用Linux的 logrotate 工具自动处理。
效果验证:优化前后对比确认提速
优化后(比如给 orders 表添加了联合索引):
ALTER TABLE orders ADD INDEX idx_status_time (status, create_time);
再次执行相同慢SQL并记录执行时间:
SELECT * FROM orders WHERE status = 'pending' AND create_time < '2023-01-01';
在 mysql 命令行中默认会显示执行时间(毫秒)。
优化前8秒的查询,现在可能降到0.02秒。
最后,再次运行 mysqldumpslow 检查慢查询日志,确保之前的慢SQL不再出现。
如果依然出现,说明还有其他问题,需要继续分析 EXPLAIN 结果或检查服务器参数(如 innodb_buffer_pool_size)。
如果你正在处理数据库慢查询分析优化性能,建议先按本文步骤完整执行,再根据自己的环境做微调;
遇到异常时优先回看避坑和高频问题部分。