慢查询日志是mysql性能优化的核心工具之一,掌握其配置、分析和优化方法,是架构师和dba必备的核心技能。
本文将从基础概念到实战优化,全面讲解慢查询日志的使用方法和最佳实践。
一、什么是慢查询日志
慢查询日志(slow query log)是 mysql 内置的日志功能,专门用于记录执行时间超过预设阈值(long_query_time)的 sql 语句。它就像mysql的“性能黑匣子”,能精准定位执行效率低下的sql,是数据库性能优化的核心抓手。
二、核心作用
- 性能诊断:快速定位系统中执行效率低的sql语句,找到性能短板。
- 瓶颈定位:分析慢查询的根因(如全表扫描、索引缺失、锁等待等)。
- 优化依据:为sql改写、索引调整、数据库参数优化提供数据支撑。
- 容量规划:通过慢查询趋势,预判数据库性能瓶颈和扩容需求。
三、配置参数详解
通过以下命令可查看所有慢查询相关配置参数:
-- 查看慢查询相关参数 show variables like '%slow%'; -- 查看慢查询阈值参数 show variables like '%long_query_time%';
核心配置参数说明:
| 参数名 | 取值 | 说明 |
|---|---|---|
slow_query_log | off/on | 是否开启慢查询日志(默认关闭) |
slow_query_log_file | 路径字符串 | 慢查询日志文件的存储路径(如/var/log/mysql/slow.log) |
long_query_time | 数值(秒) | 慢查询阈值,默认10秒(mysql 5.7+支持微秒级,如0.5表示500毫秒) |
min_examined_row_limit | 数值 | 最少检查行数阈值,低于该值的慢查询不记录(默认0) |
log_queries_not_using_indexes | off/on | 是否记录未使用索引的查询(即使执行时间未达阈值) |
log_slow_admin_statements | off/on | 是否记录慢管理语句(如alter table、analyze table等) |
log_output | file/table/none | 日志输出方式:文件/数据库表/不输出 |
四、开启和配置
1. 临时开启(重启失效)
适用于临时调试,mysql重启后配置会恢复默认值:
-- 开启慢查询日志 set global slow_query_log = 'on'; -- 设置慢查询阈值为2秒 set global long_query_time = 2; -- 指定日志文件路径 set global slow_query_log_file = '/var/log/mysql/slow.log'; -- 记录未使用索引的查询 set global log_queries_not_using_indexes = 'on';
2. 永久开启(修改配置文件)
修改mysql配置文件(my.cnf/my.ini),重启后生效,适用于生产环境:
[mysqld] # 开启慢查询日志(1=开启,0=关闭) slow_query_log = 1 # 日志文件路径 slow_query_log_file = /var/log/mysql/slow.log # 慢查询阈值(秒) long_query_time = 2 # 记录未使用索引的查询 log_queries_not_using_indexes = 1 # 日志输出到文件 log_output = file # 可选:记录慢管理语句 log_slow_admin_statements = 1 # 可选:最少检查行数阈值 min_examined_row_limit = 100
修改完成后重启mysql服务:
# centos/rhel systemctl restart mysqld # ubuntu/debian systemctl restart mysql
五、慢查询日志格式分析
典型日志条目
# time: 2024-01-01t10:00:00.123456z # user@host: root[root] @ localhost [] id: 5 # query_time: 5.123456 lock_time: 0.001000 rows_sent: 10 rows_examined: 1000000 set timestamp=1672560000; select * from users where last_name like '%smith%' order by create_time desc;
关键字段解释
| 字段名 | 说明 |
|---|---|
time | 查询执行的时间戳(utc时间) |
user@host | 执行查询的用户和主机信息 |
id | 数据库连接id |
query_time | 查询总执行时间(秒,含微秒) |
lock_time | 查询过程中锁等待时间(秒) |
rows_sent | 返回给客户端的行数 |
rows_examined | 数据库扫描的行数(核心指标,行数越多性能越差) |
rows_affected | 受dml语句(update/delete/insert)影响的行数 |
timestamp | 查询开始的unix时间戳 |
六、慢查询分析工具
1. mysqldumpslow(mysql 自带)
mysql内置的轻量级分析工具,无需额外安装,适合快速汇总慢查询:
# 按查询时间排序,显示最慢的前10条 mysqldumpslow -s t -t 10 /var/log/mysql/slow.log # 按执行次数排序 mysqldumpslow -s c /var/log/mysql/slow.log # 按锁时间排序 mysqldumpslow -s l /var/log/mysql/slow.log # 分析特定用户的慢查询(保留原始sql) mysqldumpslow -a -g "root" /var/log/mysql/slow.log
2. pt-query-digest(percona toolkit)
percona出品的专业分析工具,功能强大,是生产环境首选:
安装(以centos为例):
yum install percona-toolkit -y
常用命令:
# 基础分析,输出详细报告 pt-query-digest /var/log/mysql/slow.log # 分析最近12小时的慢查询 pt-query-digest --since=12h /var/log/mysql/slow.log # 分析指定时间段的慢查询 pt-query-digest --since='2024-01-01 00:00:00' --until='2024-01-01 23:59:59' /var/log/mysql/slow.log # 将分析结果输出到文件 pt-query-digest /var/log/mysql/slow.log > /tmp/slow_report_$(date +%y%m%d).txt
3. mysqlslow(第三方工具)
轻量级第三方工具,安装简单,输出结果直观:
# 安装(需先安装pip) pip install mysqlslow # 分析慢查询日志 mysqlslow /var/log/mysql/slow.log
七、慢查询日志表模式
除了文件存储,mysql还支持将慢查询日志存储到数据库表中,便于sql查询分析。
启用表模式存储:
-- 设置日志输出到表(file,table 表示同时输出到文件和表) set global log_output = 'table'; -- 开启慢查询日志 set global slow_query_log = 'on'; -- 查询慢查询日志表 select * from mysql.slow_log;
表结构:
show create table mysql.slow_log;
核心字段说明:
| 字段名 | 类型 | 说明 |
|---|---|---|
start_time | datetime(6) | 查询开始时间(含微秒) |
query_time | time(6) | 查询执行时间 |
lock_time | time(6) | 锁等待时间 |
rows_sent | int unsigned | 返回行数 |
rows_examined | int unsigned | 扫描行数 |
sql_text | longtext | sql语句内容 |
user_host | mediumtext | 用户和主机信息 |
注意:表模式存储会增加数据库写入压力,生产环境建议优先使用文件模式。
八、最佳实践和优化建议
1. 阈值设置建议
阈值需根据业务场景调整,避免记录过多无效日志或遗漏关键慢查询:
-- 生产环境(平衡性能和排查需求) set global long_query_time = 2; -- 2秒阈值 -- 开发/测试环境(严格排查) set global long_query_time = 0.5; -- 500毫秒 -- 高并发核心业务(微秒级监控,mysql 5.7+) set global long_query_time = 0.1; -- 100毫秒
2. 日志轮转配置
避免慢查询日志文件过大,使用logrotate实现日志自动轮转:
# /etc/logrotate.d/mysql-slow
/var/log/mysql/slow.log {
daily # 每日轮转
rotate 30 # 保留30天日志
missingok # 日志文件不存在时不报错
compress # 压缩旧日志
delaycompress # 延迟压缩(保留最新的轮转文件未压缩)
notifempty # 空文件不轮转
create 640 mysql mysql # 新建日志文件的权限和属主
postrotate # 轮转后执行的命令
mysqladmin flush-logs # 刷新日志,生成新文件
endscript
}3. 定期分析计划
编写自动化脚本,每日分析慢查询并归档,示例:
#!/bin/bash
# /usr/local/bin/analyze_slow_log.sh
# 脚本功能:每日分析慢查询日志并归档
# 定义变量
date=$(date +%y%m%d)
log_path="/var/log/mysql"
report_path="${log_path}/reports"
slow_log="${log_path}/slow.log"
# 创建报告目录
mkdir -p ${report_path}
# 使用pt-query-digest分析日志并生成报告
pt-query-digest ${slow_log} > ${report_path}/slow_report_${date}.txt
# 备份并清空原日志文件
cp ${slow_log} ${log_path}/slow.log.${date}
> ${slow_log}
# 清理30天前的旧报告
find ${report_path} -name "slow_report_*.txt" -mtime +30 -delete添加到crontab,每日凌晨执行:
# 编辑crontab crontab -e # 添加以下内容 0 0 * * * /usr/local/bin/analyze_slow_log.sh > /dev/null 2>&1
九、性能监控和告警
1. 监控慢查询数量
通过mysql状态变量实时监控慢查询数量:
-- 查看累计慢查询数量 show global status like 'slow_queries'; -- 查看当前正在执行的慢查询 show processlist; -- 或更详细的信息 show full processlist;
2. 慢查询告警脚本
编写脚本监控慢查询数量,超过阈值时发送告警:
#!/bin/bash
# /usr/local/bin/slow_query_alert.sh
# 配置参数
mysql_cmd="mysql -uroot -p'你的密码' -e"
threshold=100 # 慢查询阈值
alert_email="admin@example.com"
# 获取当前慢查询总数
slow_count=$($mysql_cmd "show global status like 'slow_queries'" | grep slow_queries | awk '{print $2}')
# 对比阈值并发送告警
if [ $slow_count -gt $threshold ]; then
subject="【告警】mysql慢查询数量异常"
content="当前慢查询总数:${slow_count},超过阈值${threshold}!\n请及时登录数据库排查慢查询。"
echo -e ${content} | mail -s "${subject}" ${alert_email}
fi添加到crontab,每分钟执行一次:
* * * * * /usr/local/bin/slow_query_alert.sh > /dev/null 2>&1
十、注意事项
- 性能影响:开启慢查询日志会增加约1-3%的数据库性能开销(主要是磁盘i/o),生产环境需评估后开启。
- 磁盘空间:慢查询日志增长较快,必须配置日志轮转,避免占满磁盘。
- 敏感信息:日志中可能包含用户密码、业务敏感数据,需限制日志文件的访问权限(如仅root和mysql用户可读取)。
- 版本差异:mysql 5.7+支持
long_query_time的微秒级精度,5.6及以下版本仅支持秒级;8.0版本默认日志格式有小幅调整。 - 测试验证:开启慢查询后,需执行
select sleep(3);(假设阈值为2秒)验证日志是否正常记录。 - 索引记录:
log_queries_not_using_indexes开启后,会记录大量简单的无索引查询(如select * from t limit 1),需结合min_examined_row_limit过滤。
面试回答(精简版)
慢查询日志是mysql记录执行时间超过阈值sql的核心工具,就像数据库的“性能病历本”,是优化的关键依据。
核心回答要点:
- 开启配置:生产环境通过修改
my.cnf永久开启,核心参数包括slow_query_log=1(开启)、long_query_time=2(阈值)、log_queries_not_using_indexes=1(记录无索引查询)。 - 分析工具:常用
mysqldumpslow(快速汇总)和pt-query-digest(专业分析),重点关注query_time(执行时间)、rows_examined(扫描行数)等字段。 - 优化思路:找到慢查询后,用
explain分析执行计划,核心优化手段包括:添加合适的索引、改写sql(避免select *、优化子查询)、调整数据库参数(如缓冲池)。 - 最佳实践:生产环境设置合理阈值(2秒),配置日志轮转,定期自动分析并设置告警,平衡性能开销和问题排查需求。
总结
- 慢查询日志是mysql性能优化的核心工具,核心配置参数为
slow_query_log(开关)、long_query_time(阈值)、log_queries_not_using_indexes(无索引查询记录)。 - 生产环境建议通过修改配置文件永久开启,结合
logrotate实现日志轮转,使用pt-query-digest进行专业分析。 - 慢查询优化的核心思路是:通过日志定位慢sql → 用
explain分析执行计划 → 针对性优化(加索引/改sql/调参数),并建立定期分析和告警机制。
到此这篇关于mysql慢查询日志从配置到优化实践全解析的文章就介绍到这了,更多相关mysql慢查询日志内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论