Springboot中分析SQL性能的两种方式

embedded/2025/2/22 5:30:02/

SQL性能分析的两种方式:

功能介绍

  • 记录 SQL 执行时间,超过阈值会进行警告
  • 打印完整的 SQL 语句,便于调试和优化
  • 适用于开发和测试环境,生产环境建议关闭

实现方式:

方式一:使用 MyBatis-Plus 性能分析插件

首先需要在MyBatis-Plus配置类中配置PerformanceInterceptor插件:

java">@Configuration
public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 添加分页拦截器(如果使用分页)interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 添加性能分析拦截器PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();performanceInterceptor.setMaxTime(500); // SQL 最大执行时间(毫秒),超过自动警告performanceInterceptor.setFormat(true); // 是否格式化 SQL 语句interceptor.addInnerInterceptor(performanceInterceptor);return interceptor;}
}

配置项说明:

配置项说明示例
setMaxTime(long maxTime)设置 SQL 执行的最大时长(单位:ms),超过时间将抛出异常,默认 -1(不限制)performanceInterceptor.setMaxTime(500); // 超过 500ms 警告
setFormat(boolean format)是否格式化 SQL,默认 false,开启后会美化 SQL 输出performanceInterceptor.setFormat(true);

日志输出:

当查询执行时间超过 maxTime 限制时,控制台会输出:

[SQL] ==> Preparing: SELECT * FROM orders WHERE status = ?
[SQL] ==> Parameters: 1(Integer)
[SQL] <== Total Time: 850 ms (超过最大时间 500ms,可能存在性能问题)

由于MyBatis-Plus 3.4.0 以后已经将上述插件弃用,所以如果你使用高版本的MyBatis-Plus,推荐使用方式二.

方式二:使用p6spy框架
效果图:

![[Pasted image 20250220124225.png]]

实现步骤:

1.引入pom依赖:

<dependency><groupId>p6spy</groupId><artifactId>p6spy</artifactId><version>3.9.1</version>
</dependency>

2.首先在 springboot配置类中加入配置:

  • 把原来的JDBC Driver替换为com.p6spy.engine.spy.P6SpyDriver.
  • 在原来urljdbc:后面添加p6spy:,比如jdbc:p6spy:mysql://127.0.0.1:3306/databse
  • 添加p6spy的配置文件spy.properties.

配置文件内容如下:

module.log=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory  
# 自定义日志打印  
logMessageFormat=warren.reggie.common.P6SpyLogger  
#logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat  
#customLogMessageFormat=%(currentTime) | SQL耗时: %(executionTime) ms | 连接信息: %(category)-%(connectionId) | 执行语句: %(sql)# 使用控制台记录sql  
appender=com.p6spy.engine.spy.appender.StdoutLogger  
## 配置记录Log例外  
excludecategories=info,debug,result,batc,resultset  
# 设置使用p6spy driver来做代理  
deregisterdrivers=true  
# 日期格式  
dateformat=yyyy-MM-dd HH:mm:ss  
# 实际驱动  
driverlist=com.mysql.jdbc.Driver  
# 是否开启慢SQL记录  
outagedetection=true  
# 慢SQL记录标准秒  
outagedetectioninterval=2

3.自定义日志输出格式:

  • 首先创建P6SpyLogger类:
java">package warren.reggie.common;  import com.p6spy.engine.spy.appender.MessageFormattingStrategy;  
import java.time.LocalDateTime;  
import java.time.format.DateTimeFormatter;  /**  * 自定义 P6Spy SQL 日志格式(带颜色)  * author: Warren  */public class P6SpyLogger implements MessageFormattingStrategy {  // ANSI 颜色代码  private static final String RESET = "\u001B[0m";  // 重置颜色  private static final String RED = "\u001B[31m";   // 红色(高亮错误)  private static final String GREEN = "\u001B[32m"; // 绿色(SQL 语句)  private static final String YELLOW = "\u001B[33m";// 黄色(执行时间)  private static final String BLUE = "\u001B[34m";  // 蓝色(分类)  private static final String CYAN = "\u001B[36m";  // 青色(连接 ID)  /**  * 自定义 SQL 日志格式(带颜色)  *  * @param connectionId 连接 ID  * @param now 当前时间(P6Spy 传递的)  * @param elapsed SQL 执行时间(ms)  * @param category SQL 类型(如 statement、commit、rollback)  * @param prepared 预编译 SQL(带 ? 占位符)  * @param sql 真实 SQL 语句(占位符替换后的)  * @param url 数据库连接 URL  * @return 格式化后的日志字符串  */  @Override  public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {  // 过滤空 SQL        if (sql == null || sql.trim().isEmpty()) {  return "";  }  // 格式化当前时间  String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));  // 构造带颜色的日志输出  return String.format(  "%s[%s]%s | %s耗时: %d ms%s | %s连接: %d%s | %s分类: %s%s\n%s执行 SQL: %s%s;\n",  CYAN, currentTime, RESET,           // 时间(青色)  YELLOW, elapsed, RESET,            // 执行时间(黄色)  BLUE, connectionId, RESET,         // 连接 ID(蓝色)  RED, category, RESET,              // 分类(红色)  GREEN, sql.trim(), RESET           // SQL 语句(绿色)  );  }  
}
  • 然后将配置文件中的格式化器属性改为自己的类 :
# 自定义日志打印  
logMessageFormat=warren.reggie.common.P6SpyLogger  

http://www.ppmy.cn/embedded/164237.html

相关文章

springcloud和springboot部署区别

Spring Cloud和Spring Boot在部署方面存在一些关键的区别&#xff0c;这些区别主要体现在它们的用途、依赖关系以及部署的复杂性上。 Spring Boot的部署特点 独立部署&#xff1a; Spring Boot应用可以打包成独立的可执行jar或war文件&#xff0c;这使得部署变得非常简单。 …

Mysql 迁移 dm 数据库

参考链接 MySQL 5.7.27 迁移 DM 8 语雀 达梦数据库DTS工具使用方法 | 达梦技术社区 迁移前准备 以下中的命名&#xff0c;密码都是可修改的&#xff0c;这里给出的就只是一个例子 1&#xff09;创建表空间 # 创建表空间名为 dbTest&#xff0c;路径为 Z:\fei\data\dm\dbTes…

游戏引擎学习第109天

回顾目前进展 在这一期中&#xff0c;讨论了游戏开发中的一个重要问题——如何处理Z轴值的表示&#xff0c;尤其是在一个3D游戏中&#xff0c;如何更好地表示和存储这些值。上次的进展中&#xff0c;已经解决了透视投影的问题&#xff0c;意味着渲染部分的Z轴代码基本上已经完…

中文Build a Large Language Model (From Scratch) 免费获取全文

中文pdf下载地址&#xff1a;https://pan.baidu.com/s/1aq2aBcWt9vYagT2-HuxdWA?pwdlshj 提取码&#xff1a;lshj 原文、代码、视频项目地址&#xff1a;https://github.com/rasbt/LLMs-from-scratch 翻译工具&#xff1a;沉浸式翻译&#xff08;https://app.immersivetrans…

DeepSeek vs ChatGPT:AI 领域的华山论剑,谁主沉浮?

一、引言 在当今科技飞速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已然成为推动各领域变革的核心力量。而在人工智能的众多分支中&#xff0c;自然语言处理&#xff08;NLP&#xff09;因其与人类日常交流和信息处理的紧密联系&#xff0c;成为了最受瞩目的领…

什么是网关,网关的作用是什么?网络安全零基础入门到精通实战教程!

1. 什么是网关 网关又称网间连接器、协议转换器&#xff0c;也就是网段(局域网、广域网)关卡&#xff0c;不同网段中的主机不能直接通信&#xff0c;需要通过关卡才能进行互访&#xff0c;比如IP地址为192.168.31.9(子网掩码&#xff1a;255.255.255.0)和192.168.7.13(子网掩码…

ue5 Arch vis AI traffic system 车辆系统添加不同种类的车

一、前置条件 资源包拥有二、步骤 添加第二辆车 在父级蓝图底下创建子级蓝图 打开子级蓝图 替换骨骼网格体 创建动画蓝图&#xff0c;骨骼选择该骨骼网格体的骨骼 连接动画蓝图 添加动画蓝图 添加资源包

jsDoc 注释规范

jsDoc 注释规范 定义 jsDoc 是一种用于 JavaScript 代码的注释规范&#xff0c;它通过特定的标签和格式&#xff0c;帮助开发者为代码添加详细的文档说明。这些注释可以被各种工具和编辑器解析&#xff0c;生成 API 文档或提供代码提示&#xff0c;极大地提升了代码的可读性和…