必须修改MySQL配置文件而非仅用SET GLOBAL设置slow_query_log等参数,否则重启失效;生产环境long_query_time建议设为1.0,log_queries_not_using_indexes应关闭以防日志爆炸。

直接改配置文件,别只用 SET GLOBAL
线上环境改 slow_query_log 或 long_query_time 仅用 SET GLOBAL 是无效的——服务重启后全丢。必须编辑 MySQL 配置文件(Linux 是 /etc/my.cnf 或 /etc/mysql/my.cnf,Windows 是 my.ini),在 [mysqld] 段落下写死:
slow_query_log = ON slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 1.0 log_queries_not_using_indexes = OFF
log_queries_not_using_indexes = OFF 很关键:生产库如果打开它,日志会爆炸式增长(尤其有大量小查询但没走索引时),反而掩盖真正耗时长的语句。除非你正做索引普查,否则别开。
long_query_time 设成 0 不等于“记录所有 SQL”
long_query_time = 0 确实会让所有查询都进慢日志,但有两个隐藏代价:
- MySQL 5.7+ 中,
long_query_time是以**秒为单位的浮点数**,设为 0 后,连执行 0.0001s 的SELECT 1也会被记录,日志体积和 I/O 压力陡增 - 某些版本(如 MySQL 8.0.23)在
long_query_time = 0时,Rows_examined字段可能不准,干扰后续分析
测试环境建议设为 0.5,生产环境保守起见用 1.0;对延迟敏感的核心业务(如支付、库存),可单独设为 0.1,但必须配合日志轮转策略(比如 logrotate 每小时切一次)。
查不到慢查询?先确认 slow_query_log_file 权限和路径
即使配置写了 slow_query_log = ON,日志仍为空,大概率是权限或路径问题:
- MySQL 进程用户(通常是
mysql)必须对slow_query_log_file所在目录有写权限,且文件名不能包含 ~ 或 $HOME 等变量 - 用
SHOW VARIABLES LIKE 'slow_query_log_file'查到的路径,要手动ls -l看父目录属主和权限;常见错误是路径写成/home/mysql/slow.log,但/home/mysql目录属主是 root,MySQL 进程无法创建文件 - 若未显式指定
slow_query_log_file,MySQL 默认写到datadir下,而datadir通常在/var/lib/mysql/,该目录下生成的host-name-slow.log文件容易被误删或忽略
刚开启就爆出大量慢查询?别急着优化,先看 Rows_examined
日志里第一条看起来像慢查询的语句,未必真有问题。重点看每条日志末尾的 Rows_examined 值:
-
# Rows_examined: 1000000+Query_time: 0.8s:说明扫描了百万行才出结果,大概率缺索引或条件没打中索引,优先处理 -
# Rows_examined: 1+Query_time: 1.2s:只查 1 行却花了 1.2 秒,可能是锁等待(Lock_time字段会高)、磁盘 I/O 延迟、或查询被大事务阻塞,这时加索引没用 -
# Rows_examined: 0:这类基本是管理类语句(如SHOW PROCESSLIST),直接过滤掉
真正要盯住的是 Rows_examined 高 + Query_time 高的组合——这才是索引设计或 SQL 写法的真实瓶颈点。其他情况,得结合 Lock_time、Rows_sent 和应用上下文判断,不能只看时间阈值。


















