定位java应用高耗时sql应启用mysql慢查询日志,通过show variables检查并配置slow_query_log、long_query_time等参数,配合mybatis注释标记和jdbc调优确保sql可追溯,再用mysqldumpslow或pt-query-digest分析日志。

在 Java 应用中定位高耗时 SQL,关键不是只看应用层日志,而是要让 MySQL 主动记录执行时间超阈值的 SQL。慢查询日志(Slow Query Log)是 MySQL 原生、低开销、最可靠的诊断手段。
确认 MySQL 是否已启用慢查询日志
登录 MySQL 执行以下命令检查当前状态:
SHOW VARIABLES LIKE 'slow_query_log'; -- ON/OFF<br>SHOW VARIABLES LIKE 'long_query_time'; -- 默认 10 秒,可设为 0.1、0.5 等<br>SHOW VARIABLES LIKE 'slow_query_log_file'; -- 日志文件路径
若未开启,需修改 MySQL 配置(my.cnf 或 my.ini):
[mysqld]<br>slow_query_log = ON<br>slow_query_log_file = /var/log/mysql/mysql-slow.log<br>long_query_time = 0.5<br>log_queries_not_using_indexes = OFF -- 按需开启,避免日志爆炸
修改后重启 MySQL 或动态生效(MySQL 5.6+):
SET GLOBAL slow_query_log = ON;<br>SET GLOBAL long_query_time = 0.5;
Java 应用侧配合:确保 SQL 可追溯
慢日志只记录原始 SQL 和执行时间,不带上下文。为快速定位到 Java 代码,建议:
- 使用 注释标记:在 MyBatis 的 XML 或注解 SQL 中添加
/* user-service-findById */类注释,MySQL 会原样记入慢日志 - 开启 JDBC 的 useServerPrepStmts=false&cachePrepStmts=false(开发/测试环境),避免预编译掩盖真实 SQL 结构
- Spring Boot 可配置
spring.jpa.properties.hibernate.generate_statistics=true辅助分析,但不能替代慢日志
分析慢查询日志的实用方法
直接读取日志文件效率低,推荐组合工具提升效率:
-
mysqldumpslow(MySQL 自带):
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log—— 按总耗时排序,取 Top 10 -
pt-query-digest(Percona Toolkit)更强大:
pt-query-digest /var/log/mysql/mysql-slow.log --limit 10—— 输出详细统计、索引建议、QPS 趋势 - 用 grep + awk 快速过滤特定模块:
grep "user-service" /var/log/mysql/mysql-slow.log | awk '/Query_time/{print $0; getline; print}'
常见陷阱与优化提示
慢日志开了 ≠ 问题自动解决,注意这些细节:
-
long_query_time 是按秒浮点数,设为
0.1表示 100ms,不是 100ms 整数;MySQL 5.7+ 支持微秒级精度(如0.05) -
默认不记录管理语句(如 ALTER、ANALYZE),如需监控 DDL 性能,加参数
log_slow_admin_statements=ON - 日志文件权限要给 MySQL 进程可写,否则启动失败或静默丢弃;生产环境建议配合
logrotate切割 - Java 中的
PreparedStatement占位符(?)在慢日志里显示为具体值,便于复现,但敏感字段需注意脱敏策略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











