数据库越来越慢拖垮整站?从慢查询日志开始查

来源:互联网 时间:2026-09-29

首页秒开,点进内页要等好几秒;后台登录转半天圈;重启一下 MySQL 能好一阵,过两天又慢回去——这是典型的数据库把整站拖垮。很多人第一反应是升级服务器配置,其实先花十分钟打开慢查询日志,把拖后腿的语句揪出来,往往不用多花钱就能解决大半。MySQL数据库优化最划算的一步就在这里。

一、先确认慢的是数据库,不是别的地方

别急着改配置,先确认病灶。做法有两个:一是用 curl 看本站的 TTFB,如果响应时间集中在服务端处理,就往数据库方向查;二是登录数据库执行 show processlist,看有没有长时间停在 Sending data 状态的语句,同时用 top 看 CPU 是否集中在 mysqld 进程上。下面这条命令把当前所有连接和它们正在做的事列出来,重点看 Time 和 State 两列。要改的是把 root 换成有 PROCESS 权限的账号。跑完看到 Time 已经几百秒、State 还停在 Sending data 的语句,那基本就是它卡住了前端。

# 查看当前正在执行的语句,找长时间运行的查询

mysql -u root -p -e "SHOW FULL PROCESSLIST\G" | head -60

# 关注 Time(已执行秒数)和 State(如 Sending data、Sorting result)

二、打开慢查询日志,把慢语句长期记下来

用 SET GLOBAL 开日志只在当前会话有效,重启就没了,所以正式环境要写进配置文件。下面这段加到 my.cnf 的 [mysqld] 段里。要改的是 long_query_time 阈值(一般设 1 秒,慢站可以先设 2 秒减少噪声)和日志路径;比较重要的是最后那行,它会把没走索引的查询也记下来,是发现隐患的好帮手。改完重启 mysqld,随便跑几条查询,然后 tail 一下日志文件,有内容就说明开了。

# 写入 /etc/my.cnf 的 [mysqld] 段,重启后依然生效

slow_query_log = 1

long_query_time = 1

slow_query_log_file = /var/log/mysql/slow.log

log_queries_not_using_indexes = 1

# 重启生效:systemctl restart mysqld

# 验证:tail -f /var/log/mysql/slow.log

三、EXPLAIN 看病灶:盯住三种典型信号

把日志里最慢的那条 SQL 复制出来,前面加 EXPLAIN 执行一次,看四列。type 是 ALL,说明走了全表扫描,几十万行的表就靠这一条能拖垮整站;key 是 NULL,说明没用到索引;rows 是预估扫描行数,越大越糟;Extra 里出现 Using temporary(用临时表)或 Using filesort(文件排序),都是排序和分组没走索引的信号。针对这些信号,给 WHERE、ORDER BY、JOIN 用到的字段补上合适的索引,再复测。

-- 看执行计划,重点四列

EXPLAIN SELECT id, title, created_at

FROM article

WHERE category_id = 12 AND status = 1

ORDER BY created_at DESC

LIMIT 20;

-- 关注 type / key / rows / Extra

-- 若 type=ALL、key=NULL,补上组合索引:

ALTER TABLE article ADD INDEX idx_cat_status_time (category_id, status, created_at);

四、改完复测,把结论沉淀成规则

改完不能凭感觉说变快了。把旧日志改名归档,让 MySQL 重新开一份,观察一整天再汇总一次,看最慢的前十条是不是换了人。下面这段就是归档加复测的组合,第一行改名不必用 mv 手动腾,flush-logs 会重新打开日志文件。跑完用 mysqldumpslow 排序,和优化前的榜单对比,原来那几条消失了才算有效。同时把这次的经验写进团队规则:凡是出现在 WHERE 里的字段都要评估索引,列表页一律分页,深分页走主键游标。

# 归档当前慢日志并开启新日志,观察一天后复测

mysqladmin -u root -p flush-logs

mv /var/log/mysql/slow.log /var/log/mysql/slow.log.$(date +%F) 2>/dev/null

# 一天后重新汇总,确认慢语句是否换人

mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

数据库变慢几乎都有迹可循,慢查询日志里写得清清楚楚,怕的是一直靠猜。定位到具体语句,优化就有了抓手,哪怕只解决掉最慢的一条,整站体验都会有明显不同。

相关阅读:

《MySQL数据库优化:索引、慢查询与参数调优的完整思路》

《内存天天跑满、服务被系统杀掉?先找出是谁在吃内存》

《网站日志怎么看?access.log 关键字段与异常识别》

相关文章

A5创业网 版权所有

返回顶部