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

 更新时间:2026年01月21日 16:46:28   作者:小Mie不吃饭  
慢查询日志是MySQL性能优化的关键工具,记录执行时间超过阈值的SQL语句,帮助定位性能瓶颈和优化SQL,本文介绍MySQL慢查询日志从配置到优化实践全解析,感兴趣的朋友跟随小编一起看看吧

慢查询日志是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_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

十、注意事项

  • 性能影响:开启慢查询日志会增加约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慢查询日志内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql去重的两种方法详解及实例代码

    mysql去重的两种方法详解及实例代码

    这篇文章主要介绍了mysql去重的两种方法详解及实例代码的相关资料,这里对去重的两种方法进行了一一实例详解,需要的朋友可以参考下
    2017-01-01
  • 计算机二级考试MySQL知识点 mysql alter命令

    计算机二级考试MySQL知识点 mysql alter命令

    这篇文章主要为大家详细介绍了计算机二级考试MySQL知识点,详细介绍了mysql中alter命令的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • 如何修改MYSQL5.7.17数据库存储文件的路径

    如何修改MYSQL5.7.17数据库存储文件的路径

    在搭建华为云服务器的时候遇到点问题,查看了网上好多的帖子都没能解决,不知道有没有跟我遇到一样问题的老铁,我就把我的解决办法分享给大家,希望能够帮助各位老铁
    2023-05-05
  • mysql insert if not exists防止插入重复记录的方法

    mysql insert if not exists防止插入重复记录的方法

    在 MySQL 中,插入(insert)一条记录很简单,但是一些特殊应用,在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,本文介绍的就是这个问题的解决方案。
    2011-04-04
  • mysql忘记root密码的解决办法(针对不同mysql版本)

    mysql忘记root密码的解决办法(针对不同mysql版本)

    这篇文章主要介绍了mysql忘记root密码的解决办法(针对不同mysql版本),文章通过代码示例和图文结合的方式给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-06-06
  • CentOS7环境下安装MySQL5.5数据库

    CentOS7环境下安装MySQL5.5数据库

    大家好,本篇文章主要讲的是CentOS7环境下安装MySQL5.5数据库,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • MySQL中索引与视图的用法与区别详解

    MySQL中索引与视图的用法与区别详解

    索引与视图是我们在日常使用mysql必不可少的一部分,最近在学习中看到一本书中关于这方法写的不错,所以这篇文章主要给大家介绍了关于MySQL中索引与视图的使用与区别的相关资料,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • 分享下mysql各个主要版本之间的差异

    分享下mysql各个主要版本之间的差异

    因为mysql的版本较多,而且又被oracle公司收购,所有很多朋友不是很清楚各个版本的区别,这里简单介绍下,方便需要的朋友
    2013-06-06
  • Win7下安装MySQL5.7.16过程记录

    Win7下安装MySQL5.7.16过程记录

    这篇文章主要为大家分享了Win7下安装MySQL5.7.16过程的笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • MySQL性能优化之table_cache配置参数浅析

    MySQL性能优化之table_cache配置参数浅析

    这篇文章主要介绍了MySQL性能优化之table_cache配置参数浅析,本文介绍了它的缓存机制、参数优化及清空缓存的命令等,需要的朋友可以参考下
    2014-07-07

最新评论