一、什么是慢查询日志
慢查询日志(slow query log) 是 mysql 内置的一种日志功能,用于记录执行时间超过指定阈值的 sql 语句。这是优化数据库性能的重要工具。
二、核心作用
- 性能诊断:找出执行效率低的 sql 语句
- 瓶颈定位:分析查询为什么慢(全表扫描、索引缺失等)
- 优化依据:为 sql 优化和索引调整提供数据支持
三、配置参数详解
-- 查看所有慢查询相关参数 show variables like '%slow%'; show variables like '%long_query_time%'; -- 主要配置参数: -- slow_query_log = off/on # 是否开启慢查询日志 -- slow_query_log_file = /path/name # 日志文件路径 -- long_query_time = 10 # 阈值(秒),默认10秒 -- min_examined_row_limit = 0 # 最少检查行数阈值 -- log_queries_not_using_indexes = off # 是否记录未使用索引的查询 -- log_slow_admin_statements = off # 是否记录管理语句 -- log_output = file/table/none # 输出方式
四、开启和配置
1. 临时开启(重启失效)
set global slow_query_log = 'on'; set global long_query_time = 2; -- 设为2秒 set global slow_query_log_file = '/var/log/mysql/slow.log'; set global log_queries_not_using_indexes = 'on';
2. 永久开启(修改配置文件)
# my.cnf 或 my.ini [mysqld] 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
五、慢查询日志格式分析
典型日志条目
# 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;
关键字段解释
- query_time:查询执行总时间
- lock_time:锁定时间
- rows_sent:返回给客户端的行数
- rows_examined:扫描的行数
- rows_affected:影响的行数(update/delete/insert)
六、慢查询分析工具
1.mysqldumpslow(mysql 自带)
# 按查询时间排序 mysqldumpslow -s t /var/log/mysql/slow.log # 按锁时间排序 mysqldumpslow -s l /var/log/mysql/slow.log # 按执行次数排序 mysqldumpslow -s c /var/log/mysql/slow.log # 显示前10条最慢的查询 mysqldumpslow -t 10 /var/log/mysql/slow.log # 分析特定用户的慢查询 mysqldumpslow -a -g "root" /var/log/mysql/slow.log
2.pt-query-digest(percona toolkit)
# 分析慢查询日志 pt-query-digest /var/log/mysql/slow.log # 分析最近12小时的慢查询 pt-query-digest --since=12h /var/log/mysql/slow.log # 输出到文件 pt-query-digest /var/log/mysql/slow.log > slow_report.txt
3.mysqlslow(第三方工具)
mysqlslow /var/log/mysql/slow.log
七、慢查询日志表模式
启用表模式存储
set global log_output = 'table'; set global slow_query_log = 'on'; -- 查询慢查询日志 select * from mysql.slow_log;
表结构
show create table mysql.slow_log; -- 主要字段: -- start_time: 查询开始时间 -- query_time: 查询耗时 -- lock_time: 锁定时间 -- rows_sent: 返回行数 -- rows_examined: 检查行数 -- sql_text: sql语句 -- user_host: 用户和主机信息
八、最佳实践和优化建议
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
/var/log/mysql/slow.log {
daily
rotate 30
missingok
compress
delaycompress
notifempty
create 640 mysql mysql
postrotate
mysqladmin flush-logs
endscript
}
3.定期分析计划
# 每日分析脚本示例
#!/bin/bash
date=$(date +%y%m%d)
pt-query-digest /var/log/mysql/slow.log > /var/log/mysql/slow_report_${date}.txt
# 清空日志文件(先备份)
cp /var/log/mysql/slow.log /var/log/mysql/slow.log.${date}
echo "" > /var/log/mysql/slow.log
九、性能监控和告警
1. 监控慢查询数量
-- 监控每分钟的慢查询数量 show global status like 'slow_queries'; -- 查看当前慢查询 show processlist;
2. 慢查询告警脚本
#!/bin/bash
slow_count=$(mysql -e "show global status like 'slow_queries'" | grep slow_queries | awk '{print $2}')
threshold=100
if [ $slow_count -gt $threshold ]; then
echo "警告:慢查询数量异常!当前数量: $slow_count" | mail -s "mysql慢查询告警" admin@example.com
fi
十、注意事项
性能影响:开启慢查询日志会有约1-3%的性能开销
磁盘空间:定期清理,避免日志文件过大
敏感信息:日志可能包含敏感数据,需妥善保管
生产环境:建议设置合理的阈值,避免记录过多无关查询
版本差异:mysql 5.7+ 支持微秒级精度,之前版本只到秒
面试回答
简单来说,慢查询日志就像是 mysql 的一个‘病历本’。它会自动记录下来所有执行时间超过某个阈值的 sql 语句。这样我们开发或者 dba 就能知道,哪些查询是‘慢’的、有问题的,然后去针对性地优化。
在实际工作中,我主要会关注和操作这么几个方面:
第一,怎么开启和设置。
慢查询日志默认是关闭的,因为它会有一点磁盘 i/o 的开销。我们需要在 mysql 配置文件(比如 my.cnf)里设置几个核心参数:
slow_query_log = on:打开开关。slow_query_log_file:指定这个‘病历本’文件存哪里。long_query_time:这是最重要的一个阈值,单位是秒。比如设为 1,就意味着执行超过 1 秒的 sql 才会被记录。这个值可以根据系统性能要求来调整。log_queries_not_using_indexes:这个我也经常会打开。它会记录那些没有使用索引的查询,即使它执行得很快。这能帮我们发现潜在的设计问题。
第二,怎么看这个日志。
日志是文本格式,可以直接看,但不太直观。我常用的方法是:
- 用 mysql 自带的
mysqldumpslow工具。这个命令行工具可以对日志进行汇总、排序,比如我们可以用mysqldumpslow -t 10 -s t来找出耗时最长的前 10 条 sql,一目了然。 - 对于更复杂的分析,我会用 percona 公司开的 ****
pt-query-digest工具。它功能更强大,能给出非常详细的报告,比如每个 sql 的响应时间占比、执行次数、锁时间等,能帮我快速定位最需要优化的‘瓶颈’ sql。
第三,也是最重要的,找到慢 sql 后怎么办。
光找到没用,关键是要优化。我一般的排查思路是:
1、拿到这条慢 sql,先用 explain 命令去看它的执行计划。这是标准动作。我会重点看:
- 有没有用到索引(
key字段)。 - 扫描了多少行(
rows字段)。 - 查询类型是不是全表扫描(
type字段,如果是all就不好了)。
2、根据 ****explain ****的结果,常见的优化手段就是:
- 加索引:这是最有效的办法之一,检查
where、order by、join的字段。 - 优化 sql 本身:比如避免
select *,检查是否有复杂的子查询能不能改写为join,或者分页查询在大偏移量时有没有优化空间。 - 看看是不是数据库参数问题,比如缓冲池大小是不是不合理。
最后,我的一点实践经验是:慢查询日志在测试环境和生产环境都很有用。在项目上线前,我们会开启它来提前发现一些性能问题。在生产环境,我们会长期开启,但会设置一个合理的 long_query_time(比如从 2 秒开始),并定期归档和分析日志,把它作为性能监控和容量规划的一个重要依据。
以上就是一文带大家深入了解下mysql中的慢查询日志的详细内容,更多关于mysql慢查询日志的资料请关注代码网其它相关文章!
发表评论