慢查询日志未记录需先确认mysql服务端配置是否生效,包括slow_query_log=on、long_query_time合理设置、配置写入my.cnf并重启;再用explain分析执行计划,重点检查type=all及索引覆盖情况。

慢查询日志没记录?先确认 MySQL 配置是否生效
Go 应用本身不生成慢查询日志,slow_query_log 和 long_query_time 是 MySQL 的服务端配置项。常见错误是只在 Go 里开 db.SetLogger 或 GORM 的 LogMode,结果看到的只是“SQL 发了”,完全不知道它执行了多久、扫了多少行。
- 登录 MySQL 执行
SHOW VARIABLES LIKE 'slow_query_log';,确认值为ON - 开发环境建议设
SET GLOBAL long_query_time = 0.1;(单位秒),默认 10 秒基本等于没开 -
slow_query_log_file路径通常在/var/lib/mysql/xxx-slow.log,不是 Go 项目目录下 - MySQL 8.0+ 默认关闭慢日志,
SET GLOBAL重启即失效,必须写进/etc/mysql/my.cnf的[mysqld]段并重启服务
EXPLAIN 显示 type=ALL?大概率缺索引
拿到慢 SQL 后第一件事不是改 Go 代码,而是直接在 MySQL 里跑 EXPLAIN。如果 type 列是 ALL,且 rows 值远大于实际返回行数(比如查 5 行却扫描 24 万行),就是典型全表扫描。
-
WHERE条件字段必须建索引:如WHERE tradeofferid = ? AND accepted = ?,应建复合索引idx_trade_accepted (tradeofferid, accepted) -
ORDER BY字段也要覆盖:如ORDER BY created_at DESC,可单独建idx_created_at (created_at),或纳入复合索引最右位 - 字符串字段注意长度:若
tradeofferid是VARCHAR(64),建索引时要显式指定长度,如INDEX idx_tradeid (tradeofferid(32)),否则可能因隐式截断失效 - 避免冗余索引:
tradeofferid单列索引在已有(tradeofferid, accepted)复合索引时完全多余,会拖慢写操作
GORM 或原生 sql.DB 怎么记录真实慢 SQL 耗时
context.WithTimeout 控制的是 Go 程序等待结果的上限,不是测量 SQL 在数据库里真实执行时间。想监控“哪条 SQL 真慢”,得在驱动层打点。
- 原生
sql.DB没钩子机制,必须包装database/sql/driver.Conn,在Query/Exec方法里统一计时;只在外层套time.Now()会漏掉网络往返和 DB 执行时间 - GORM 推荐用内置 logger:必须显式设
SlowThreshold,例如config.SlowThreshold = 200 * time.Millisecond;只开LogMode不设阈值,等于全量日志,根本分不清哪条真慢 - 日志默认不带参数值;如需脱敏后参数,要实现自定义
logger.Writer,但上线建议关到Warn级别,避免反射开销放大延迟
APM 工具能定位到具体接口,但别跳过执行计划验证
Skywalking、Pinpoint 这类 APM 可以快速关联慢 SQL 和业务接口,比如看到 “订单列表接口耗时 2.5s,其中一条 SQL 占 2.3s”。但它不告诉你为什么慢——这一步必须人工补上 EXPLAIN 和索引检查。
- APM 日志里看到的 SQL 往往带占位符(
?),复制出来要替换成实际值再跑EXPLAIN,否则执行计划可能不同 - 某些管控系统(如 GaussDB 管控平台)会高频查
pg_locks,导致lockmgrlock等待事件,让所有 SQL 都变慢;这种场景下 APM 会误报“慢 SQL”,实际是监控采集干扰 - 连接池耗尽也会表现为大量 SQL 延迟升高,但每条单独看都不慢;此时
SHOW PROCESSLIST和SELECT COUNT(*) FROM information_schema.PROCESSLIST比看慢日志更有效
真实慢 SQL 往往卡在“看不见”的地方:索引缺失、锁竞争、监控干扰、连接池排队。光靠 Go 层日志或 APM 报警只能指个方向,最终得回到 MySQL 服务端,用 EXPLAIN 和 SHOW PROCESSLIST 看清每一行到底在等什么。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











