当前位置: 首页 > news >正文

看看人家的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 呢?

原来是这样的:

  1. 如果批量语句中的某些语句失败,则默认重写会导致所有语句都失败。

  2. 批量语句的某些语句参数不一样,则默认重写会使得查询缓存未命中。

看起来影响不大,所以我给我的项目设置上了这个参数!

 

最后

稍微总结下我粗略的对比(虽然粗略,但实验结果符合原理层面的理解),如果你想更准确地实验,可以使用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】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥求正数数…...

物联网LoRa系列-2:从感知到应用,详解LoRa在分层架构中的关键角色

1. LoRa技术入门:从无线通信到物联网连接 第一次接触LoRa是在五年前的一个智慧农业项目上。当时客户需要在2000亩的茶园部署环境监测系统,传统WiFi和4G网络要么覆盖不足,要么功耗太高。当我看到LoRa终端设备在单节电池供电下能工作3年时&…...

实战指南:如何用AKShare在3分钟内构建Python金融数据应用

实战指南:如何用AKShare在3分钟内构建Python金融数据应用 【免费下载链接】akshare AKShare is an elegant and simple financial data interface library for Python, built for human beings! 开源财经数据接口库 项目地址: https://gitcode.com/gh_mirrors/aks…...

ABAQUS多孔介质渗流分析保姆级教程:从渗透系数设置到Soil分析步详解

ABAQUS多孔介质渗流分析实战指南:从零搭建渗流模型 第一次打开ABAQUS进行多孔介质分析时,面对密密麻麻的参数选项,大多数工程师都会感到无从下手。渗流分析作为岩土工程、生物力学等领域的基础仿真需求,其核心难点不在于理论复杂度…...

3分钟快速指南:如何用VoiceFixer免费修复模糊语音录音

3分钟快速指南:如何用VoiceFixer免费修复模糊语音录音 【免费下载链接】voicefixer General Speech Restoration 项目地址: https://gitcode.com/gh_mirrors/vo/voicefixer 你是否曾为模糊不清的会议录音而烦恼?是否因为背景噪音导致重要对话无法…...

实测Taotoken聚合API的延迟与稳定性表现

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 实测Taotoken聚合API的延迟与稳定性表现 作为一名需要频繁调用大模型API的开发者,选择一个稳定、响应迅速的服务平台至…...

Beyond Compare 5授权机制深度解析:如何构建一个完整的密钥生成系统

Beyond Compare 5授权机制深度解析:如何构建一个完整的密钥生成系统 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen Beyond Compare 5作为一款专业的文件对比工具,其授权…...

从零到一:单总线CPU硬布线控制器设计与三级时序系统实战解析(Logisim Educoder)

1. 单总线CPU硬布线控制器设计入门 第一次接触单总线CPU设计时,我完全被各种专业术语搞晕了。直到在Logisim里亲手搭建电路,才真正理解硬布线控制器的精妙之处。简单来说,硬布线控制器就像CPU的"交通警察",它通过硬件电…...

TEA5767收音机模块避坑指南:STM32 I2C通信那些容易忽略的细节

TEA5767收音机模块避坑指南:STM32 I2C通信那些容易忽略的细节 在嵌入式音频开发领域,TEA5767作为经典的FM收音模块,凭借其高集成度和简单易用的特性,成为许多STM32项目的首选。然而在实际开发中,不少工程师都会遇到信号…...

别再死记硬背了!一张图帮你理清O-RAN架构里的O1、A1、E2接口到底管什么

解码O-RAN三大核心接口:O1、A1、E2的实战化理解指南 面对O-RAN架构中纷繁复杂的接口文档,许多工程师的第一反应往往是"这些接口到底有什么区别?"传统技术文档习惯用表格对比参数,却很少回答一个根本问题:这些…...

ComfyUI-Manager完整指南:如何快速搭建和管理你的AI工作流

ComfyUI-Manager完整指南:如何快速搭建和管理你的AI工作流 【免费下载链接】ComfyUI-Manager ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and enable various c…...