外观
MySQL 慢查询日志分析
慢查询日志配置
启用慢查询日志
临时启用(会话级别)
sql
-- 启用慢查询日志
SET SESSION slow_query_log = 'ON';
-- 设置慢查询阈值(单位:秒)
SET SESSION long_query_time = 1;
-- 设置慢查询日志文件路径
SET SESSION slow_query_log_file = '/var/log/mysql/mysql-slow.log';
-- 记录未使用索引的查询
SET SESSION log_queries_not_using_indexes = 'ON';
-- 记录管理语句
SET SESSION log_slow_admin_statements = 'ON';永久启用(全局级别)
ini
[mysqld]
# 启用慢查询日志
slow_query_log = 1
# 设置慢查询阈值
long_query_time = 0.5
# 设置慢查询日志文件路径
slow_query_log_file = /var/log/mysql/mysql-slow.log
# 记录未使用索引的查询
log_queries_not_using_indexes = 1
# 记录管理语句
log_slow_admin_statements = 1
# 记录执行时间超过阈值的查询
log_output = FILE
# 限制慢查询日志大小
max_slowlog_size = 100M
# 慢查询日志文件数量
slow_query_log_rotation = 10配置参数详解
long_query_time
- 查询执行时间阈值
- 精度可设置到微秒级别
- 建议根据业务需求调整
log_queries_not_using_indexes
- 记录未使用索引的查询
- 有助于发现索引缺失问题
- 可能会产生大量日志,建议谨慎启用
log_slow_admin_statements
- 记录管理语句(如ALTER TABLE、ANALYZE TABLE等)
- 这些语句可能执行时间较长
min_examined_row_limit
- 只记录扫描行数超过此值的查询
- 避免记录扫描少量行的查询
慢查询日志格式
日志条目结构
# Time: 2023-01-01T12:00:00.000000Z
# User@Host: root[root] @ localhost [] Id: 12345
# Query_time: 2.500000 Lock_time: 0.100000 Rows_sent: 100 Rows_examined: 10000
SET timestamp=1672574400;
SELECT * FROM users WHERE age > 30 ORDER BY name;关键字段解析
- Time:查询执行时间
- User@Host:执行查询的用户和主机
- Query_time:查询执行时间(秒)
- Lock_time:锁等待时间(秒)
- Rows_sent:返回的行数
- Rows_examined:扫描的行数
- SET timestamp:查询执行的时间戳
- SQL语句:实际执行的SQL语句
日志格式类型
- FILE:写入文件
- TABLE:写入mysql.slow_log表
- FILE,TABLE:同时写入文件和表
慢查询日志分析工具
MySQL自带工具
mysqldumpslow
- MySQL自带的慢查询日志分析工具
- 简单易用,适合快速分析
- 支持按不同维度排序
安装
- 随MySQL一起安装
- 位于MySQL安装目录的bin目录
使用示例
bash
# 查看帮助
mysqldumpslow --help
# 按查询时间排序,显示前10条
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
# 按扫描行数排序,显示前10条
mysqldumpslow -s r -t 10 /var/log/mysql/mysql-slow.log
# 显示使用了全表扫描的查询
mysqldumpslow -s t -t 10 -g "Full scan" /var/log/mysql/mysql-slow.log
# 分析指定数据库的慢查询
mysqldumpslow -s t -t 10 -d test /var/log/mysql/mysql-slow.log排序选项
- t:按查询时间排序
- l:按锁时间排序
- r:按扫描行数排序
- a:按平均查询时间排序
- c:按查询次数排序
Percona Toolkit
pt-query-digest
- Percona开发的专业慢查询日志分析工具
- 功能强大,提供详细的分析报告
- 支持多种输出格式
- 可分析实时MySQL流量
安装
bash
# Debian/Ubuntu
sudo apt-get install percona-toolkit
# CentOS/RHEL
sudo yum install percona-toolkit使用示例
bash
# 分析慢查询日志文件
pt-query-digest /var/log/mysql/mysql-slow.log
# 分析实时MySQL流量
pt-query-digest --processlist h=localhost,u=root,p=password
# 按执行时间排序,显示前20条
pt-query-digest --limit=20 /var/log/mysql/mysql-slow.log
# 将结果输出到文件
pt-query-digest /var/log/mysql/mysql-slow.log > slow_query_report.txt
# 分析指定时间范围内的慢查询
pt-query-digest --since='2023-01-01 00:00:00' --until='2023-01-02 00:00:00' /var/log/mysql/mysql-slow.log报告解读
- 总体统计:查询总数、总执行时间、平均执行时间等
- 响应时间分布:不同执行时间范围的查询分布
- 用户统计:按用户分组的查询统计
- 主机统计:按主机分组的查询统计
- SQL统计:按SQL语句分组的详细统计
- 执行计划:查询的执行计划分析
其他工具
MySQL Enterprise Monitor
- 企业级监控工具
- 提供图形化的慢查询分析
- 实时监控和告警
- 集成到MySQL Enterprise Edition
MySQL Workbench
- MySQL官方提供的GUI工具
- 包含性能分析功能
- 可视化执行计划
- 适合开发人员使用
第三方工具
- Neor ProfileSQL:开源的SQL分析工具
- Jet Profiler:商业SQL性能分析工具
- EverSQL:在线SQL优化工具
慢查询分析方法
基本分析步骤
- 启用慢查询日志
- 收集足够的慢查询数据
- 使用分析工具处理日志
- 识别慢查询模式
- 分析执行计划
- 实施优化措施
- 验证优化效果
关键指标分析
查询执行时间
- 总执行时间
- 平均执行时间
- 执行时间分布
锁等待时间
- 锁等待时间占比
- 锁类型分析
- 锁等待原因
扫描行数与返回行数
- 扫描行数与返回行数的比例
- 全表扫描情况
- 索引使用效率
索引使用情况
- 未使用索引的查询
- 索引使用不当的查询
- 缺失索引的情况
常见慢查询模式
全表扫描
- 未使用索引
- WHERE条件不适合使用索引
- 索引选择性差
多表连接
- 连接表过多
- 连接条件未使用索引
- 连接顺序不合理
复杂子查询
- 相关子查询
- 子查询嵌套过深
- 子查询未优化
排序和分组
- 大量数据排序
- ORDER BY未使用索引
- GROUP BY操作效率低
函数操作
- 在WHERE条件中使用函数
- 函数导致索引失效
- 复杂表达式计算
慢查询优化技巧
索引优化
- 添加合适的索引
- 优化复合索引顺序
- 避免过度索引
- 定期重建碎片化索引
SQL语句优化
- 减少SELECT *,只选择需要的列
- 优化WHERE条件,使用索引友好的表达式
- 避免在WHERE条件中使用函数
- 优化JOIN操作,小表驱动大表
- 分解复杂查询为简单查询
数据库结构优化
- 合理设计表结构
- 规范化与反规范化平衡
- 使用分区表
- 适当使用视图和存储过程
配置优化
- 调整内存参数
- 优化InnoDB缓冲池
- 调整连接参数
- 优化查询缓存(MySQL 5.7及以下)
应用层面优化
- 使用缓存,减少数据库访问
- 批量操作替代单条操作
- 异步处理非关键操作
- 实现读写分离
慢查询监控与管理
实时监控
- 配置慢查询日志实时分析
- 使用监控工具实时监控慢查询
- 设置慢查询告警阈值
定期分析
- 建立慢查询分析周期
- 生成定期分析报告
- 跟踪慢查询趋势
日志管理
- 配置日志轮转
- 控制日志大小
- 归档历史日志
- 清理过期日志
自动化处理
- 编写脚本自动分析慢查询
- 自动识别新出现的慢查询
- 自动生成优化建议
- 集成到CI/CD流程
常见问题(FAQ)
Q1: 如何确定合适的慢查询阈值?
A1: 确定慢查询阈值应考虑:
- 业务需求:不同业务对响应时间的要求不同
- 系统配置:硬件性能影响查询执行时间
- 高峰期与低谷期:可设置不同的阈值
- 历史数据:分析历史查询执行时间分布
- 建议:从小值开始(如0.1秒),根据实际情况调整
Q2: 慢查询日志会影响MySQL性能吗?
A2: 启用慢查询日志会对MySQL性能产生一定影响:
- 额外的I/O操作:写入日志文件
- 额外的CPU开销:记录和处理慢查询
- 影响程度取决于:
- 慢查询数量
- 日志文件写入速度
- 存储设备性能
- 建议:
- 在生产环境中合理设置阈值
- 考虑使用FILE,TABLE双格式
- 定期轮换和清理日志
Q3: 如何处理大量的慢查询日志?
A3: 处理大量慢查询日志的方法:
- 启用日志轮转,控制单个文件大小
- 使用pt-query-digest等工具进行聚合分析
- 提取关键信息,忽略重复查询
- 建立慢查询归档策略
- 考虑使用外部存储系统存储历史日志
Q4: 为什么有些快查询也会出现在慢查询日志中?
A4: 可能的原因:
- 锁等待时间:查询本身执行快,但等待锁的时间长
- 系统负载:系统负载高时,查询执行时间变长
- 缓存失效:首次执行时缓存未命中
- 统计信息过时:执行计划选择不当
- 参数设置:某些参数影响查询执行时间
Q5: 如何区分慢查询和正常查询的边界?
A5: 区分方法:
- 基于业务SLA:根据服务级别协议确定
- 基于历史数据:分析查询执行时间分布
- 基于资源使用:考虑CPU、I/O等资源消耗
- 基于用户体验:考虑用户感知的响应时间
- 动态调整:根据系统负载和业务情况动态调整阈值
