慢查询日志配置
慢查询日志是性能优化的入口:先把「哪条语句慢」变成可查的证据,再谈优化。开启之后,执行时间超过阈值的语句会被记录下来,配合执行计划与统计信息就能定位瓶颈。阈值是最关键的参数,默认十秒对多数线上系统都太宽松——真正拖垮系统的是那些执行零点几秒却每秒上千次的高频查询,它们永远上不了默认榜单。
基本信息
| 用途 | 记录超过阈值的语句作为优化依据 |
|---|---|
| 关键参数 | long_query_time,默认十秒 |
| 输出位置 | 文件或数据表两种模式 |
| 固化方式 | 写入配置文件并纳入版本管理 |
| 相关开关 | 未使用索引的语句记录、日志限流 |
| 适用版本 | MySQL 5.7 / 8.0,参数名一致 |
典型使用场景
- 新系统上线后建立慢查询基线,作为后续优化的参照
- 接口突然变慢的排查:确认是否出现新的慢语句
- 索引调整或版本升级后的效果验收
- 定期巡检输出慢语句榜单,安排优化排期
- 配合会话与事务视图定位等待、锁相关的问题
- 容量评估:按慢语句分布判断该加索引还是加资源
动态开启
动态开启
SET GLOBAL slow_query_log = ON; # 打开慢查询日志
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log'; # 指定输出文件
SET GLOBAL long_query_time = 1; # 阈值按秒计,支持小数,如 0.5
SET GLOBAL log_queries_not_using_indexes = OFF; # 未走索引的语句默认不开,避免日志暴涨
SHOW VARIABLES LIKE 'slow%'; # 确认各参数已生效配置文件固化
配置文件固化
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_throttle_queries_not_using_indexes = 60 # 未走索引语句的写入限流,单位秒
min_examined_row_limit = 100 # 扫描行数太少就不记,减少噪音
log_output = FILE # 也可写为 TABLE,但表模式会占用实例资源关键参数对照
| 参数 | 含义 | 建议 |
|---|---|---|
| long_query_time | 超过该秒数才记录 | 线上从半秒到一秒起步,逐步收紧 |
| slow_query_log | 总开关 | 可就地开启,长期应固化到配置 |
| slow_query_log_file | 输出文件路径 | 确认目录存在且磁盘有空间 |
| log_output | 输出到文件或数据表 | 文件模式更适合批量分析 |
| log_queries_not_using_indexes | 记录未使用索引的语句 | 高并发下日志暴涨,必须配合限流 |
| min_examined_row_limit | 扫描行数下限 | 过滤噪音,聚焦真正昂贵的语句 |
| log_throttle_queries_not_using_indexes | 未用索引语句的限流 | 限制单位时间内的记录条数 |
打开未使用索引的记录却不配限流,高并发下日志文件会迅速膨胀,既拖慢写入又可能把磁盘写满,属于自己造出来的故障。
阈值不能照搬默认值:十秒会漏掉绝大多数真实瓶颈,建议从一秒起步、结合业务基线逐步下调,同时用扫描行数下限把噪音挡在外面。
慢查询日志是实例级开关,动态修改会影响整个实例;只想观察某个连接时可只在该会话内调整阈值,避免波及其他业务。
慢日志运维清单
- 日志目录单独规划,配置轮转与保留周期
- 监控日志文件大小与磁盘余量,避免写满
- 定期把慢日志解析成榜单,分配给具体负责人
- 优化完成后复测同一语句,确认耗时确实下降
- 开关与阈值变更记录进变更单
- 避免把慢日志与数据文件放在同一块盘上
慢日志里记录的是执行耗时,不包含锁等待时间:一条语句可能执行很快却长时间被锁挡住,这类问题要结合会话视图与事务视图一起看,不能只盯慢日志。