2. 慢查询日志配置:MySQL慢查询日志开启、慢查询时间阈值设置、日志分析工具介绍

慢查询日志是数据库性能调优的“第一现场”。在Go项目上线后,如果某个接口响应突然变慢,第一件事就是检查慢查询日志——它记录了所有执行时间超过设定阈值的SQL语句,是定位数据库瓶颈最直接的证据。

2.1 慢查询日志的开启与配置

MySQL默认关闭慢查询日志,需要手动开启。以下是在线开启(无需重启)的推荐方式:

-- 开启慢查询日志(全局生效,重启后失效)
SET GLOBAL slow_query_log = ON;

-- 设置日志文件路径
SET GLOBAL slow_query_log_file = '/var/log/mysql/mysql-slow.log';

-- 设置慢查询时间阈值(单位:秒,推荐生产环境设为 0.5~1 秒)
SET GLOBAL long_query_time = 1;

-- 记录未使用索引的查询(强烈建议开启)
SET GLOBAL log_queries_not_using_indexes = ON;
生产建议: 如果希望重启后配置依然生效,请将上述参数写入 my.cnf 或 my.ini 的 [mysqld] 段。注意 long_query_time 支持小数,例如 0.5 表示500毫秒。

2.2 慢查询时间阈值设置策略

阈值设置过大会漏掉慢SQL,设置过小会产生大量日志影响磁盘I/O。不同场景的推荐值如下:

场景 推荐阈值 说明
高并发OLTP(如订单、支付) 0.2 ~ 0.5 秒 要求单次查询极快,超过500ms即需关注
常规业务系统(如CMS、后台) 1 ~ 2 秒 用户可接受1秒左右响应
离线分析/报表 5 ~ 10 秒 允许较长时间的数据聚合查询
开发/测试环境 0.1 ~ 0.3 秒 尽早暴露潜在慢查询
避坑: 不要在生产环境将 long_query_time 设为 0。这会记录所有查询,导致日志文件在几分钟内膨胀到GB级别,拖慢磁盘并影响MySQL性能。建议从 1 秒开始,逐步下调。

2.3 慢查询日志内容解读

一条典型的慢查询日志记录包含以下关键字段:

# Time: 2025-03-15T10:23:45.123456Z
# User@Host: go_app[go_app] @  [10.0.1.100]  Id: 12345
# Query_time: 2.345678  Lock_time: 0.000123  Rows_sent: 1000  Rows_examined: 500000
SET timestamp=1742029425;
SELECT u.name, o.order_amount
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.created_at > '2025-01-01'
ORDER BY o.created_at DESC;
  • Query_time:实际执行时间(秒),核心指标。
  • Lock_time:锁等待时间,过高说明存在锁竞争。
  • Rows_examined:扫描行数,远大于 Rows_sent 时说明索引缺失或查询计划不佳。
  • SET timestamp:查询发起的时间戳,用于关联业务日志。

2.4 慢查询日志分析工具介绍

手动翻阅原始日志效率极低,必须借助工具进行聚合分析。以下是Go项目中最常用的三款工具:

工具 安装方式 核心能力 适用场景
pt-query-digest Percona Toolkit 自带 按查询指纹聚合、排序、输出执行计划建议 生产环境深度分析,最推荐
mysqldumpslow MySQL 自带 按平均时间/次数排序,输出TOP N 快速查看最慢的几条SQL
Bytebase SQL 审核 独立部署或SaaS 可视化慢查询看板、索引建议、历史趋势 团队协作、持续集成流程
实战命令示例:
pt-query-digest /var/log/mysql/mysql-slow.log > slow_report.txt
该命令会生成一份按总耗时降序排列的报告,前几行就是需要优先优化的“头号慢查询”。

2.5 慢查询日志分析流程(SVG)

下图展示了从日志采集到SQL优化的完整闭环流程,Go开发者应将其嵌入日常巡检SOP:

慢查询日志分析闭环流程 开启慢查询日志 采集原始日志 pt-query-digest 分析 定位TOP慢查询 索引 / SQL 优化 验证并关闭日志 持续迭代优化 💡 关键指标: • 单次慢查询优化后,Query_time 应降低 80% 以上 • 全表扫描(Rows_examined 远大于 Rows_sent)必须加索引

2.6 Go项目中的慢查询日志实践清单

  • 统一日志路径:在 my.cnf 中固定 slow_query_log_file,便于自动化采集。
  • 定时轮转:使用 logrotate 按天或按大小切割日志,防止磁盘写满。
  • 与APM联动:将慢查询日志中的 Query_time 与Go应用的接口耗时做关联,快速定位是SQL慢还是业务逻辑慢。
  • 灰度开启:先在预发布环境开启 log_queries_not_using_indexes,确认无副作用后再推至生产。
Go开发者专属提示: 在Go的数据库驱动(如 database/sql + go-sql-driver/mysql)中,可以通过设置 ?timeout=5s 连接参数实现应用层的超时保护,避免慢查询长时间阻塞goroutine。但这不能替代MySQL层面的慢查询日志——日志是事后分析的基础,超时是事中保护的手段,两者缺一不可。