Kratos需结合ORM层埋点实现SQL耗时监控:ent通过ent.Log注入日志器并提取duration_ms字段;gorm需设SlowThreshold≥Warn级别;MySQL慢日志需重连生效、慎用log_queries_not_using_indexes,并注意云数据库双开关要求。

Kratos 框架本身不内置 SQL 慢查询监控能力,必须依赖数据库层日志 + 应用层埋点组合实现,否则你看到的只是“接口慢”,根本不知道是哪条 SQL 在拖后腿。
怎么让 Kratos 记录每条 SQL 的执行耗时?
Kratos 使用 ent 或 gorm 作为 ORM 时,需手动注入 SQL 日志中间件。默认情况下,ent 不打印 SQL,gorm 需显式开启日志级别:
-
ent:在初始化ent.Client时传入ent.Log选项,例如:ent.Log(log.NewLogrus(logrus.StandardLogger())),再配合日志字段提取duration_ms字段做告警 -
gorm:设置logger.Config.SlowThreshold = time.Second,并确保logger.Config.LogLevel≥logger.Warn,否则Slow SQL不会输出 - 注意:生产环境禁用
logger.Info级别,否则每条 SQL 都打日志,I/O 直接打爆
MySQL 层慢查询日志为什么开了却没记录?
常见原因不是配置没生效,而是阈值和开关没对齐:
-
SET GLOBAL long_query_time = 1只对新连接生效,旧连接仍沿用旧值 —— 必须重连或重启应用,不能只改完就认为 OK -
log_queries_not_using_indexes开启后,哪怕一条SELECT * FROM user LIMIT 1都会被记入慢日志(因无 WHERE),导致日志量爆炸,生产环境慎用 - 检查实际日志路径:
SHOW VARIABLES LIKE 'slow_query_log_file';,别只看配置文件里写的路径,MySQL 启动时可能 fallback 到默认位置(如/var/lib/mysql/xxx-slow.log) - 某些云数据库(如阿里云 RDS)默认关闭该功能,且控制台开关和实例参数需同时开启才生效
EXPLAIN 显示 type=ALL,但字段明明有索引?
这说明优化器主动放弃了索引,不是没建,而是“不用”。典型诱因有:
- WHERE 条件对字段用了函数:
WHERE DATE(create_time) = '2024-01-01'→ 改成WHERE create_time >= '2024-01-01' AND create_time - 隐式类型转换:
user_id是VARCHAR类型,但代码里传了整数WHERE user_id = 123→ MySQL 自动转成CAST(123 AS CHAR),索引失效 - 联合索引顺序错位:
INDEX(a, b, c),但查询是WHERE b = ? AND c = ?→ 最左匹配失败,索引完全无法使用 - 统计信息过期:
ANALYZE TABLE xxx没跑过,优化器误判全表扫描比走索引便宜
真正卡住人的地方往往不在“怎么加索引”,而在于“为什么加了也不走”——这时候得看 EXPLAIN FORMAT=TREE(MySQL 8.0+)或者 OPTIMIZER_TRACE 输出,而不是只盯 key 字段有没有值。











