目录
[1. 临时开启(重启失效)](#1. 临时开启(重启失效))
[2. 永久开启(修改配置文件)](#2. 永久开启(修改配置文件))
[1. mysqldumpslow(MySQL 自带)](#1. mysqldumpslow(MySQL 自带))
[2. pt-query-digest(Percona Toolkit)](#2. pt-query-digest(Percona Toolkit))
[3. mysqlslow(第三方工具)](#3. mysqlslow(第三方工具))
[1. 阈值设置建议](#1. 阈值设置建议)
[2. 日志轮转配置](#2. 日志轮转配置)
[3. 定期分析计划](#3. 定期分析计划)
[1. 监控慢查询数量](#1. 监控慢查询数量)
[2. 慢查询告警脚本](#2. 慢查询告警脚本)
慢查询日志是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/调参数),并建立定期分析和告警机制。
