必须确认三要素:@@slow_query_log=1、@@slow_query_log_file路径存在且MySQL用户有写权限、@@long_query_time设为合理浮点值(如1.0),再用SELECT SLEEP(2)实测日志是否生成。

确认慢查询日志是否真正生效
很多人执行 SET GLOBAL slow_query_log = ON 后就以为万事大吉,结果查了一周日志发现空空如也。根本原因是:MySQL 5.7 的 long_query_time 对已存在的连接不生效,且默认值是 10 秒——你线上接口超时才 800ms,它压根不会记。
必须做三件事:
- 用
SHOW VARIABLES LIKE 'long_query_time'确认当前值,别信文档说的“默认 10”,有些发行版打了补丁会改 - 执行
SET GLOBAL long_query_time = 1(或更激进的0.5),再新建一个客户端连接测试 - 立刻跑一条明显慢的语句,比如
SELECT SLEEP(2),然后检查日志文件是否新增记录
如果没记录,90% 是权限问题:slow_query_log_file 路径的父目录必须让 mysql 用户可写,不是只看文件是否存在。
过滤掉干扰项:别让 log_queries_not_using_indexes 淹没真问题
这个参数在 MySQL 5.7 中默认关,但很多教程盲目建议开。实际一开,小表全表扫描、COUNT(*)、INFORMATION_SCHEMA 查询全涌进来,日志里 95% 是噪音。
更可控的做法是关掉它,转而用 min_examined_row_limit = 1000(单位行数)——只记录扫描超过 1000 行的语句。这样既能捕获真正伤资源的 SQL,又不会把 SELECT * FROM config WHERE type='feature_flag' 这种合理全扫也记下来。
注意:min_examined_row_limit 是 5.6.5+ 才支持的参数,5.7 完全可用,但必须写进 my.cnf 生效,SET GLOBAL 不支持动态修改。
用 mysqldumpslow 快速定位瓶颈语句
mysqldumpslow 不是万能,但它是最快筛出“高频+高耗时”组合的工具。别直接翻原始日志,先跑这两条命令:
-
mysqldumpslow -s at -t 20 /var/log/mysql/slow.log:按平均耗时排序,揪出单次最慢的几条 -
mysqldumpslow -s c -t 20 /var/log/mysql/slow.log:按出现次数排序,找出被反复调用的“慢性子”
重点盯 Rows_examined 和 Rows_sent 的比值。比如 Rows_examined: 124800 但 Rows_sent: 1,说明 99.99% 的扫描都是白干——八成是缺索引,或者用了 LIKE '%xxx' 导致索引失效。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
有个坑:mysqldumpslow 默认会把数字抽象成 N、字符串抽象成 'S',如果你要查某条具体 ID 的慢查,得加 -a 参数禁用抽象,否则搜不到原始值。
从日志跳到 EXPLAIN:为什么不能只看 Query_time
日志里的 Query_time: 1.234567 是总耗时,包含锁等待、磁盘 IO、CPU 计算,但不包括网络传输。所以看到一批 300~500ms 的“偶发慢查”,第一反应不该是改 SQL,而是查 Lock_time 字段。
如果 Lock_time 占比超过 30%,说明存在锁竞争,这时候优化 SQL 没用,得看事务边界、隔离级别、是否有长事务持有锁。
真正该拿去 EXPLAIN 的,是那些 Lock_time 很低但 Rows_examined 极高的语句。例如:
SELECT * FROM orders WHERE user_id = 123 AND status = 'pending';
如果 EXPLAIN 显示 type: ALL、key: NULL、rows: 892341,那答案很明确:建联合索引 INDEX(user_id, status),而不是单独给 user_id 加索引——因为 status 是等值查询,放前面能提升索引选择性。
最后提醒一句:MySQL 5.7 不支持 EXPLAIN ANALYZE,别浪费时间查这个命令。真实执行计划和实际耗时的偏差,只能靠 performance_schema.events_statements_summary_by_digest 补充验证。










