一句话定位:慢查询日志是 MySQL 的 "性能监控雷达" ,自动记录执行超过 long_query_time 的 SQL,是定位性能瓶颈的黄金标准。
一、核心工作流程
二、极速配置模板(生产直接抄)
[mysqld]
# 1. 开启慢查询日志(默认 OFF)
slow_query_log = ON
slow_query_log_file = /data/mysql/log/slow.log # 建议独立磁盘
# 2. 时间阈值(秒),0.1 = 100ms
long_query_time = 0.1
# 3. 记录未使用索引的查询(默认 OFF)
log_queries_not_using_indexes = ON
# 4. 日志格式(TABLE 支持 SQL 查询,FILE 传统)
log_output = FILE,TABLE # 同时写文件和 mysql.slow_log 表
# 5. 采样率(避免日志过大)
log_throttle_queries_not_using_indexes = 100 # 每分钟最多记录 100 条无索引查询
# 6. 管理语句(ALTER, ANALYZE 等)
log_slow_admin_statements = ON
# 7. 记录到表的最大行数
slow_log_table_size = 10000 # mysql.slow_log 表最多 1 万行三、关键参数详解
1. slow_query_log(开关)
slow_query_log = ON动态开启 :
SET GLOBAL slow_query_log = ON;无需重启 ,但建议配置文件中静态设置
2. long_query_time(阈值)
long_query_time = 0.1 # 100ms单位:秒 ,支持小数
推荐值 :
互联网业务:
0.1~0.5(100ms~500ms)后台/报表:
1~2
动态调整 :
SET GLOBAL long_query_time = 0.1;会话级测试 :
SET SESSION long_query_time = 0;记录所有查询
3. log_queries_not_using_indexes(无索引查询)
log_queries_not_using_indexes = ON作用:即使执行时间很短,只要没走索引就记录
注意:可能导致日志暴增,配合
log_throttle_queries_not_using_indexes使用
4. log_throttle_queries_not_using_indexes(限速)
log_throttle_queries_not_using_indexes = 100作用 :每分钟最多记录 100 条无索引查询,防日志打爆
推荐 :
100~1000
5. log_slow_admin_statements(管理语句)
log_slow_admin_statements = ON作用 :记录
ALTER TABLE,ANALYZE,CREATE INDEX等推荐 :
ON,慢 DDL 影响业务
四、日志分析工具(实战命令)
1. mysqldumpslow(MySQL 自带)
# 按执行时间排序,Top 10
mysqldumpslow -s t -t 10 /data/mysql/log/slow.log
# 按平均锁定时间排序
mysqldumpslow -s al -t 10 /data/mysql/log/slow.log
# 过滤特定表
mysqldumpslow -t 10 -g 'users' /data/mysql/log/slow.log2. pt-query-digest(Percona Toolkit,强烈推荐)
# 安装
yum install percona-toolkit
# 分析慢查询日志,生成报告
pt-query-digest /data/mysql/log/slow.log > slow_report.html
# 按时间范围分析
pt-query-digest --since='2024-01-01 00:00:00' \
--until='2024-01-01 23:59:59' \
/data/mysql/log/slow.log > report.html
# 功能:
# - 按总耗时、平均耗时、锁定时间排序
# - 显示执行计划(EXPLAIN)
# - 推荐索引
# - 可视化图表五、生产环境实践
1. 日志切割与归档
# 每天凌晨切割慢查询日志
# /etc/cron.daily/mysql_slow_log_rotate
#!/bin/bash
LOG_DIR="/data/mysql/log"
DATE=$(date +%Y%m%d)
mv ${LOG_DIR}/slow.log ${LOG_DIR}/slow.log.${DATE}
mysqladmin flush-logs slow # 通知 MySQL 重新打开日志
# 压缩旧日志
gzip ${LOG_DIR}/slow.log.${DATE}
# 保留 30 天
find ${LOG_DIR} -name "slow.log.*" -mtime +30 -delete2. 存储位置建议
[mysqld]
# 慢查询日志推荐独立磁盘,避免与数据盘竞争 IO
slow_query_log_file = /ssd/log/slow.log
# 或独立分区挂载
# /dev/nvme1n1p1 /ssd/log ext4 defaults,noatime 0 03. 性能影响
开销 :< 5%(CPU 和 I/O)
风险 :日志文件过大(> 100GB)会影响日志轮转
缓解 :配合
log_throttle_queries_not_using_indexes
4. 慢查询日志表
-- 查看 mysql.slow_log 表(需 log_output=TABLE)
SELECT * FROM mysql.slow_log
ORDER BY query_time DESC
LIMIT 10;
-- 优点:可用 SQL 直接查询
-- 缺点:表过大影响性能,需定期清理
TRUNCATE TABLE mysql.slow_log;六、慢查询优化流程(实战)
1. 发现慢查询
pt-query-digest --since=24h /data/mysql/log/slow.log > report.html
2. 定位 TOP 1 查询
# report.html 显示:
# Query 1: 平均耗时 2.3s, 执行 1000 次, 扫描 100 万行
3. EXPLAIN 分析
mysql> EXPLAIN SELECT * FROM users WHERE phone='13800138000';
# 结果:type=ALL (全表扫描)
4. 优化方案
- 添加索引: ALTER TABLE users ADD INDEX idx_phone(phone);
- 或改写 SQL: SELECT id, name FROM users WHERE phone=?;
5. 验证
mysql> EXPLAIN SELECT ...;
# 结果:type=ref (走索引)
# 再次执行: 耗时 2.3s → 10ms
6. 监控
pt-query-digest /data/mysql/log/slow.log --since='1h' | grep 'phone'
# 确认优化后不再出现七、慢查询日志告警
# 检测 1 分钟内新增慢查询数量
#!/bin/bash
LOG_FILE="/data/mysql/log/slow.log"
COUNT=$(tail -n 10000 $LOG_FILE | grep -c "$(date '+%Y-%m-%d %H:%M')")
if [ $COUNT -gt 100 ]; then
echo "告警: 1 分钟内新增 $COUNT 条慢查询" | mail -s "MySQL 慢查询告警" dba@company.com
fi八、一句话总结
慢查询日志是性能优化的唯一真相来源:long_query_time = 0.1,配合 pt-query-digest 每周生成报告,所有慢 SQL 都必须有索引,没有例外。
评论