mybatis拦截器是记录sql执行耗时与性能瓶颈最常用且推荐的方式,通过实现interceptor接口拦截executor.query()和update()方法,用instant.now()精准计时,结合boundsql.getsql()获取带参数的完整sql,并按阈值过滤、标记异常,零侵入业务代码。

Java 中记录 SQL 执行耗时与性能瓶颈,核心是把“谁在什么时候执行了哪条 SQL、花了多久、是否异常”这几个关键信息结构化捕获下来。不靠人工打点,而是借助框架能力或轻量拦截机制,让日志既可读又可分析。
用 MyBatis 拦截器统一记录 SQL 耗时
这是最常用也最推荐的方式——零侵入业务代码,能拿到完整的 SQL 语句、参数、执行结果和精确耗时。
- 实现
Interceptor接口,拦截Executor.update()和Executor.query()方法 - 在方法执行前用
Instant.now()记录起点,在执行后再次记录终点,用Duration.between()算出毫秒级耗时 - 通过
BoundSql.getSql()获取最终执行的 SQL(含参数替换后的样子),避免日志里全是问号 - 按阈值过滤,比如只记录 >500ms 的 SQL,防止日志爆炸;同时标记是否执行失败
开启 MyBatis 日志并配置慢 SQL 标记
如果不想写拦截器,可以启用 MyBatis 自带的日志功能,再配合简单规则识别慢 SQL。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在
application.yml中设置:mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl - 日志会打印每条 SQL 及其参数,但默认不带时间戳和耗时。可在日志框架(如 Logback)中添加自定义 Pattern,注入线程局部耗时变量
- 更实用的做法:结合 SLF4J MDC,在 SQL 执行前 put 一个开始时间,在执行后计算差值并写入日志上下文,让每条 SQL 日志自动带上
cost=128ms字段
对接数据库慢查询日志做交叉验证
应用层日志反映的是“Java 视角下的耗时”,而 MySQL 慢查询日志体现的是“数据库真实执行耗时”。两者对比能快速判断瓶颈在应用还是数据库。
- 在 MySQL 中开启慢查询:
SET GLOBAL slow_query_log = ON;,并设long_query_time = 0.5(单位秒) - 查出慢日志路径后,用
mysqldumpslow或pt-query-digest分析高频慢 SQL - 把应用日志中的 SQL 片段(如
SELECT * FROM user WHERE id = ?)与慢日志里的实际执行语句比对,确认是否同一调用链路
用 APM 工具自动采集全链路 SQL 性能数据
适合中大型系统,省去手动埋点,还能关联接口、服务、线程、数据库多个环节。
- Prometheus + Micrometer:在 DAO 层方法上加
@Timed注解,自动上报执行耗时分布直方图 - PINPOINT / SkyWalking:基于字节码增强,自动拦截 JDBC
PreparedStatement.execute(),记录 SQL、参数、耗时、调用栈、数据库地址等 - 这些工具生成的指标可配置告警,比如“某 SQL 平均耗时突增 300%”或“单次执行超 2s 的次数每分钟超 5 次”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










