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

news/2025/2/22 9:35:18/

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/news/1574119.html

相关文章

在mfc中使用自定义三维向量类和计算多个三维向量的平均值

先添加一个普通类, Vector3.h, // Vector3.h: interface for the Vector3 class. // //#if !defined(AFX_VECTOR3_H__53D34D26_95FF_4377_BD54_57F4271918A4__INCLUDED_) #define AFX_VECTOR3_H__53D34D26_95FF_4377_BD54_57F4271918A4__INCLUDED_#if _MSC_VER > 1000 #p…

【多模态大模型】端侧语音大模型minicpm-o:手机上的 GPT-4o 级多模态大模型

MiniCPM-o &#xff0c;它是一款 开源、轻量级 的多模态大语言模型&#xff0c;目标是在手机等资源受限的环境中实现 GPT-4o 级别的多模态能力&#xff01; 1. MiniCPM-o&#xff1a;小身材&#xff0c;大能量&#xff01; MiniCPM-o 的名字已经暗示了它的核心特点&#xff…

人工智能之自动驾驶技术体系

自动驾驶技术体系 自动驾驶技术是人工智能在交通领域的重要应用&#xff0c;旨在通过计算机视觉、传感器融合、路径规划等技术实现车辆的自主驾驶。自动驾驶不仅能够提高交通效率&#xff0c;还能减少交通事故和环境污染。本文将深入探讨自动驾驶的技术体系&#xff0c;包括感…

C++ 多态详解

文章目录 1. 什么是多态1.1 静态多态和动态多态 2. 动态多态2.1 动态多态的实现2.2 虚函数2.2.1 虚函数的重写2.2.2 虚函数协变2.2.3 析构函数的重写2.2.4 override和final 3. 动态多态原理解析3.1 _vfptr3.2 动态绑定与静态绑定3.3 虚函数表详解 4. 纯虚函数和抽象类5. 重载、…

二级公共基础之数据结构与算法篇(八)排序技术

目录 前言 一、交换类排序 1.冒泡排序法 1. 冒泡排序的思想 2. 冒泡排序的实现步骤 3. 示例 4. 冒泡排序的特点 2.快速排序 1. 快速排序的核心思想 2. 快速排序的实现步骤 3. 示例代码(C语言) 4. 快速排序的特点 二、插入类排序 1. 简单插入排序 1.简单插入排…

质因数分解

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 Nancy喜欢博弈&#xff01; Johnson和Nancy得到了一个神奇的多重集合&#xff0c;仅包含一个正整数n&#xff0c;两个人轮流进行操作。 一次操作可以将集合中一个数字分解为它的任意…

电磁铁的磁芯材质

电磁铁的磁芯通常采用软铁材质&#xff0c;因其具有高磁导率和低矫顽力&#xff0c;使得电磁铁能够在通电时迅速产生强磁场&#xff0c;断电后磁场又能迅速消失。 一、电磁铁与磁芯材质 电磁铁是一种利用电流产生磁场的装置。其核心部件——磁芯&#xff0c;对电磁铁的性能有着…

【Python项目】基于Python的Web漏洞挖掘系统

【Python项目】基于Python的Web漏洞挖掘系统 技术简介&#xff1a; 采用Python技术、MySQL数据库、Django框架、Scrapy爬虫等技术实现。 系统简介&#xff1a; Web漏洞挖掘系统是一个基于B/S架构的漏洞扫描平台&#xff0c;旨在通过自动化的方式对网站进行漏洞检测。系统主要功…