Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql慢查询日志

MySQL慢查询日志从配置到优化实践全解析

作者:小Mie不吃饭

慢查询日志是MySQL性能优化的关键工具,记录执行时间超过阈值的SQL语句,帮助定位性能瓶颈和优化SQL,本文介绍MySQL慢查询日志从配置到优化实践全解析,感兴趣的朋友跟随小编一起看看吧

慢查询日志是MySQL性能优化的核心工具之一,掌握其配置、分析和优化方法,是架构师和DBA必备的核心技能。

本文将从基础概念到实战优化,全面讲解慢查询日志的使用方法和最佳实践。

一、什么是慢查询日志

慢查询日志(Slow Query Log)是 MySQL 内置的日志功能,专门用于记录执行时间超过预设阈值(long_query_time)的 SQL 语句。它就像MySQL的“性能黑匣子”,能精准定位执行效率低下的SQL,是数据库性能优化的核心抓手。

二、核心作用

三、配置参数详解

通过以下命令可查看所有慢查询相关配置参数:

-- 查看慢查询相关参数
SHOW VARIABLES LIKE '%slow%';
-- 查看慢查询阈值参数
SHOW VARIABLES LIKE '%long_query_time%';

核心配置参数说明:

参数名取值说明
slow_query_logOFF/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_indexesOFF/ON是否记录未使用索引的查询(即使执行时间未达阈值)
log_slow_admin_statementsOFF/ON是否记录慢管理语句(如ALTER TABLE、ANALYZE TABLE等)
log_outputFILE/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_timeDATETIME(6)查询开始时间(含微秒)
query_timeTIME(6)查询执行时间
lock_timeTIME(6)锁等待时间
rows_sentINT UNSIGNED返回行数
rows_examinedINT UNSIGNED扫描行数
sql_textLONGTEXTSQL语句内容
user_hostMEDIUMTEXT用户和主机信息

注意:表模式存储会增加数据库写入压力,生产环境建议优先使用文件模式。

八、最佳实践和优化建议

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

十、注意事项

面试回答(精简版)

慢查询日志是MySQL记录执行时间超过阈值SQL的核心工具,就像数据库的“性能病历本”,是优化的关键依据。

核心回答要点:

总结

到此这篇关于MySQL慢查询日志从配置到优化实践全解析的文章就介绍到这了,更多相关mysql慢查询日志内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文