看看人家的MyBatis批量插入数据优化,从120s到2.5s,那叫一个优雅!
粗略的实验
最后
最近在压测一批接口的时候,我发现接口处理速度比我们预期的要慢。这让我感到有点奇怪,因为我们之前已经对这些接口进行了优化。但是,当我们进行排查时,发现问题出在数据库批量保存这块。
我们的项目使用了 mybatis-plus 这个工具,而批量保存我们是直接使用的 mybatis-plus 提供的 saveBatch 方法。在仔细研究了这个方法后,我发现它并没有对批量插入进行优化,而是直接循环插入数据。
我点进去看了下源码,感觉有点不太对劲:
我继续追踪了下,从这个代码来看,确实是 for 循环一条一条执行了 sqlSession.insert
,下面的 consumer 执行的就是上面的 sqlSession.insert
:
然后累计一定数量后,一批 flush。
从这点来看,这个 saveBach 的性能肯定比直接一条一条 insert 快。
我直接进行一个粗略的实验,简单创建了一张表来对比一波!
粗略的实验
1000条数据,一条一条插入
可以看到,执行一批 1000 条数的批量保存,耗费的时间是 121011 毫秒。
1000条数据用 mybatis-plus 自带的 saveBatch 插入
耗费的时间是 59927 毫秒,比一条一条插入快了一倍,从这点来看,效率还是可以的。
然后常见的还有一种利用拼接 sql 方式来实现批量插入,我们也来对比试试看性能如何。
1000条数据用手动拼接 sql 方式插入
搞个手动拼接:
来跑跑下性能如何:
耗时只有 2275 毫秒,性能比 mybatis-plus 自带的 saveBatch 好了 26 倍!
这时,我又突然回想起以前直接用 JDBC 批量保存的接口,那都到这份上了,顺带也跑跑看!
1000条数据用 JDBC executeBatch 插入
耗时是 55663 毫秒,所以 JDBC executeBatch 的性能跟 mybatis-plus
的 saveBatch 一样(底层一样)。
综上所述,拼接 sql 的方式实现批量保存效率最佳。
但是我又不太甘心,总感觉应该有什么别的法子,然后我就继续跟着 mybatis-plus 的源码 debug 了一下,跟到了 mysql 的驱动,突然发现有个 if 里面的条件有点显眼:
就是这个叫 rewriteBatchedStatements 的玩意,从名字来看是要重写批操作的 Statement,前面batchHasPlainStatements 已经是 false,取反肯定是 true,所以只要这参数是 true 就会进行一波操作。
我看了下默认是 false。
同时我也上网查了下 rewriteBatchedStatements 参数,好家伙,好像有用!我直接将 jdbcurl 加上了这个参数:
然后继续跑了下 mybatis-plus
自带的 saveBatch,果然性能大大提高,跟拼接 SQL 差不多!
顺带我也跑了下 JDBC 的 executeBatch ,果然也提高了。
然后我继续 debug ,来探探 rewriteBatchedStatements 究竟是怎么 rewrite 的!
如果这个参数是 true,则会执行下面的方法且直接返回:
看下 executeBatchedInserts
究竟干了什么:
看到上面我圈出来的代码没,好像已经有点感觉了,继续往下 debug。
果然!sql 语句被 rewrite了:
对插入而言,所谓的 rewrite 其实就是将一批插入拼接成 insert into xxx values (a),(b),(c)...
这样一条语句的形式然后执行,这样一来跟拼接 sql 的效果是一样的。
那为什么默认不给这个参数设置为 true 呢?
原来是这样的:
-
如果批量语句中的某些语句失败,则默认重写会导致所有语句都失败。
-
批量语句的某些语句参数不一样,则默认重写会使得查询缓存未命中。
看起来影响不大,所以我给我的项目设置上了这个参数!
最后
稍微总结下我粗略的对比(虽然粗略,但实验结果符合原理层面的理解),如果你想更准确地实验,可以使用JMH,并且测试更多组数(如 5000,10000等)的情况。
在处理 JDBC 的批量操作时,有两个性能方面的关键点。首先,需要注意将 rewriteBatchedStatements 设置为 true,以提高性能。其次,如果你倾向于手动拼接 SQL 语句,你需要注意一次拼接的数量并进行分批处理。此外,你也可以通过优化 SQL 查询语句的方式来提高性能。例如,使用索引、避免使用 select * 等操作,可以减少查询所需的时间和资源。还可以使用连接池来缓存数据库连接,减少每次建立连接的时间和成本。总之,通过细致地调整和优化你的数据库操作,你可以显著提高应用程序的性能和稳定性。
相关文章:

看看人家的MyBatis批量插入数据优化,从120s到2.5s,那叫一个优雅!
粗略的实验 最后 最近在压测一批接口的时候,我发现接口处理速度比我们预期的要慢。这让我感到有点奇怪,因为我们之前已经对这些接口进行了优化。但是,当我们进行排查时,发现问题出在数据库批量保存这块。 我们的项目使用了 myb…...
软件和信息服务业专题讲座
软件和信息服务业专题讲座 单选题(共 10 题,每题 3 分) 1、根据本讲,我国要加强物联网应用领域()开发和应用。 A、大数据 2、根据本讲,要充分发挥软件对城市管理和惠民服务的(&am…...

由 ChatGPT 团队开发,堪称辅助神器!IntelliJ IDEA 神级插件
什么是Bito? 为什么要使用Bito? 如何安装Bito插件 如何使用Bito插件 什么是Bito? Bito是一款由ChatGPT团队开发的IntelliJ IDEA编辑器插件,旨在提高开发人员的工作效率。此插件强大之处在于它不仅可以帮助开发人员更快地提交…...

spass modeler
课时1:SPSS Modeler 简介 本课时一共分为五个模块,分别是Modeler概述、工具安装、窗口说明以及功能介绍和应用案例。相信通过本课时内容的学习,大家将会对SPSS Modeler有个基础的了解. 在学习本节课内容之前,先来看看本节课我们究…...
kafka的push、pull分别有什么优缺点
文章目录 kafka的push、pull分别有什么优缺点Push 模式优点缺点 Pull 模式优点缺点 实践操作 kafka的push、pull分别有什么优缺点 Kafka 是由 Apache 软件基金会开发的一个开源流处理平台,广泛应用于各大互联网公司的消息系统中。在 Kafka 中,生产者使用…...

【Canvas入门】从零开始在Canvas上绘制简单的动画
这篇文章是观看HTML5 Canvas Tutorials for Beginners教程做的记录,所以代码和最后的效果比较相似,教程的内容主要关于这四个部分: 创建并设置尺寸添加元素让元素动起来与元素交互 设置Canvas的大小 获取到canvas并设置尺寸为当前窗口的大…...
【技术整合】各技术解决方案与对应解决的问题
文章目录 基本实现性能安全 本文将框架分为三大类: 基本实现:包括某个供能或者提供web、移动端、桌面端、或者上述端上的某种功能性能:提升高可用、高并发的框架安全:包括网络安全、权限与容灾等 基本实现 .NET CORE、.NET web基…...

公网远程访问公司内网象过河ERP系统「内网穿透」
文章目录 概述1.查看象过河服务端端口2.内网穿透3. 异地公网连接4. 固定公网地址4.1 保留一个固定TCP地址4.2 配置固定TCP地址 5. 使用固定地址连接 概述 ERP系统对于企业来说重要性不言而喻,不管是财务、生产、销售还是采购,都需要用到ERP系统来协助。…...

Win11的两个实用技巧系列之修改c盘大小方法、功能快捷键大全
Win11 c盘无法更改大小什么原因?Win11修改c盘大小方法 有不少朋友反应Win11 c盘无法更改大小是怎么回事?本文就为大家带来了详细的更改方法,需要的朋友一起看看吧 Win11 c卷无法更改大小什么原因?有用户电脑的系统盘空间太小了,…...

离散数学下--- 代数系统
代数系统 定义: 代数系统是用代数运算构造数学模型的方法。 • 通过构造手段生成,所以也称代数结构 • 代数运算:在集合上建立满足一定规则的运算系统 (一)二元运算 二元运算的定义 二元运算需要满足的两个条件&a…...

java基础入门-04
Java基础入门-04 11、集合&学生管理系统11.1.ArrayList集合和数组的优势对比:11.1.1 ArrayList类概述11.1.2 ArrayList类常用方法11.1.2.1 构造方法11.1.2.2 成员方法11.1.2.3 示例代码 11.1.3 ArrayList存储字符串并遍历11.1.3.1 案例需求11.1.3.2 代码实现 11…...

《面试1v1》java反射
我是 javapub,一名 Markdown 程序员从👨💻,八股文种子选手。 面试官: 你好,请问你对 Java 反射有了解吗? 候选人: 是的,我了解一些。 面试官: 那你能简单…...

【C语言】struct结构体
文章目录 一. 结构体简述二. 结构体的声明和定义1、简单地声明一个结构体和定义结构体变量2、声明结构体的同时也定义结构体变量3、匿名结构体4、配合typedef,声明结构体的同时为结构体取别名5、在声明匿名结构体时,使用typedef给这个匿名结构体取别名 三…...

Docker代码环境打包
1. 介绍 Docker是一种开源的容器化平台,它可以在操作系统级别运行应用程序。通过将应用程序及其依赖项封装成一个可移植的容器,Docker使得应用程序可以在任何环境中轻松部署、运行和管理。使用Docker,开发人员可以避免在不同环境中出现的配置…...
现代CMake高级教程 - 第 6 章:输出与变量
双笙子佯谬老师的【公开课】现代CMake高级教程课程笔记 第 6 章:输出与变量 在运行 cmake -B build 时,打印字符串(用于调试) message("Hello world!")❯ cmake --build buildHello world! -- Configuring done -- G…...

windows/linux文件传输
windows系统下文件传输-FTP python安装pyftpdlib模块 pip install pyftpdlib 这里可能会出现报错,自己看着更换源解决 然后运行python,在2121端口监听 python -m pyftpdlib 然后我们可以使用windows命令行进行操作,自己可以去看下相关文…...
Anoconda安装笔记+win10 更改中文用户名为英文
win10 更改中文用户名为英文 ① WinR打开命令窗口,输入regedit 打开注册表, 手动找到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ProfileList 在这个目录下面有几个S-1-5-的项,挨个检查每一项, 找到“…...
Java Web应用开发 ——作业七
一.单项选择题(共7题,28.7分) 1 Servlet程序的入口点是( )。 A、 init() B、 main() C、 service() D、 doGet() 正确答案&#…...
echo,date,bc命令详解
文章目录 echo,date,bc命令详解echo(输出文本)date(显示日期的命令)date命令的--date选项date命令 bc(高精度计算器) echo,date,bc命令详解 echo(输出文本) echo命令是一个常用的Shell命令,用于在终端上输出文本。它…...

【Java笔试强训 29】
🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥求正数数…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...