MySQL批量插入处理之提高速度

使用rewriteBatchedStatements属性优化Mybatis-Plus批量插入数据 由于项目是使用MyBatis-Plus开发的,用起来也确实比较方便,尤其是service层封装好的一些通用的增删改查方法,省去了不少sql语句的书写,但是在开发过程中,我也发现MyBatis-Plus的saveBatch批量插入方法针对MySQL数据库可能会出现效率贼低的情况,通过不断查询资料发现可以通过加rewriteBatchedStatements参数来解决(保证5.1.13以上版本)。 阅读详情

这是我转载的,但是我亲测了,好用!我的问题这个方法解决了!!

昨天研究了一下mysql的批处理,最初发现很慢

10000条    每次1000    243秒
50000条    每次500条   1295秒

代码如下:

[java]  view plain  copy
  1. package main;  
  2.   
  3. import java.sql.*;  
  4.   
  5. public class JdbcStreaming {  
  6.     public static void main(String[] args){  
  7.         try {  
  8.             Connection conn = ;  
  9.             Class.forName("com.mysql.jdbc.Driver").newInstance(); // MYSQL驱动  
  10.             conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_deletable?useUnicode=true&characterEncoding=UTF-8",  
  11.                             "mysql", "mysql"); // 链接本地MYSQL  
  12.             int batchSize = 50000;  
  13.             int count = 5000000;  
  14.             conn.setAutoCommit(false);//设置自动提交为false  
  15.             PreparedStatement ps = conn.prepareStatement("insert into test (id) values (?)");  
  16.             Long t1 = System.currentTimeMillis();  
  17.             System.out.println("====================");  
  18.             for (long i = 1; i < count; i++) {  
  19.                 ps.setLong(1, i);//设置第一个参数的值为i  
  20.                 ps.addBatch();//将该条记录添加到批处理中  
  21.                 if (i% batchSize == 0) {  
  22.                     ps.executeBatch();//执行批处理  
  23.                     conn.commit();//提交  
  24.                     System.out.println(i+":添加"+batchSize+"条");  
  25.                 }  
  26.             }  
  27.             if ((count+1) % batchSize != 0) {  
  28.                 ps.executeBatch();  
  29.                 conn.commit();  
  30.             }  
  31.             ps.close();  
  32.             Long t2 = System.currentTimeMillis();  
  33.             System.out.println(count+"条    每次"+batchSize+"条   "+(t2-t1)/1000+"秒");  
  34.         } catch (Exception e) {  
  35.             // TODO: handle exception  
  36.             e.printStackTrace();  
  37.         }  
  38.     }  
  39. }  

很明显,1万条数据,需要执行243秒。

这个代码的性能很低,首先排除该表的复杂性(该表只有两个字段,id为自增主键),二、排除逻辑复杂性(从代码可以看出,这段代码只是简单的把i值赋给id)

后来又调整了很多参数,但都没有找到根本原因,执行时间会有稍微提高或者没什么变化。


最后,添加参数rewriteBatchedStatements=true

即:

[java]  view plain  copy
  1. conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_deletable?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8",  
  2.                             "mysql", "mysql"); // 链接本地MYSQL  

执行时间提高100倍以上

50000条    每次500条   7秒


后续修改批处理大小,得到执行时间不一样。

5000000条    每次500条   849秒

5000000条    每次5000条   179秒

5000000条    每次50000条   90秒

5000000条    每次100000条   211秒


可以看出来,批处理大小的设置,也是影响执行时间的一个重要原因,但并不是设置的越大越好,或者越小越好。


下面介绍一下rewriteBatchedStatements

MySql的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入。


MySQL Jdbc驱动在默认情况下会无视executeBatch()语句,把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,直接造成较低的性能。
 
只有把rewriteBatchedStatements参数置为true, 驱动才会帮你批量执行SQL (jdbc:mysql://ip:port/db?rewriteBatchedStatements=true)。

另外,有人说rewriteBatchedStatements只对INSERT有效,有人说它对UPDATE/DELETE也有效。为此我做了一些实验(详见下文),结论是: 这个选项对INSERT/UPDATE/DELETE都有效,只不过对INSERT它为会预先重排一下SQL语句。
 
 
实验记录:未打开rewriteBatchedStatements时


未打开rewriteBatchedStatements时,根据wireshark嗅探出的mysql报文可以看出,
batchDelete(10条记录)  =>  发送10次delete 请求
batchUpdate(10条记录)  =>  发送10次update 请求
batchInsert(10条记录)  =>  发送10次insert 请求
 
也就是说,batchXXX()的确不起作用
 
实验记录:打开了rewriteBatchedStatements后


打开rewriteBatchedStatements后,根据wireshark嗅探出的mysql报文可以看出
 
batchDelete(10条记录)  =>  发送一次请求,内容为”delete from t where id = 1; delete from t where id = 2; delete from t where id = 3; ….”
batchUpdate(10条记录)  =>  发送一次请求,内容为”update t set … where id = 1; update t set … where id = 2; update t set … where id = 3 …”
batchInsert(10条记录)  =>   发送一次请求,内容为”insert into t (…) values (…) , (…), (…)”
 
对delete和update,驱动所做的事就是把多条sql语句累积起来再一次性发出去;而对于insert,驱动则会把多条sql语句重写成一条风格很酷的sql语句,然后再发出去。 官方文档说,这种insert写法可以提高性能(”This is considerably faster (many times faster in some cases) than using separate single-row INSERT statements”)
 
一个注意事项


需要注意的是,即使rewriteBatchedStatements=true, batchDelete()和batchUpdate()也不一定会走批量:  当batchSize <= 3时,驱动会宁愿一条一条地执行SQL 。所以,如果你想验证rewriteBatchedStatements在你的系统里是否已经生效,记得要使用较大的batch.



mybatis的批处理(效率)之rewriteBatchedStatements和allowMultiQueries mybatis的批处理效率小结 内容说明: mysql数据库为例 rewriteBatchedStatements=true:批量将数据传给mysql allowMultiQueries=true:允许一次性执行多条sql 更多配置项 ==> 资料入口 文章目录mybatis的批处理效率小结一:说明rewriteBatchedStatements1、如何配置2、引入依赖3、测试案例(使用原生jdbc测试)4、运行结果:4、注意事项和小结:二、说明allowMultiQueries1、如何配置2、 阅读详情

相关推荐

51单片机IAP在线升级实战:从Bootloader设计到HEX文件合并

本文详细介绍了51单片机IAP在线升级的完整实战方案,重点解析了Bootloader的设计原理与内存分区规划。通过配置Keil工程实现代码地址偏移,并利用XMODEM协议进行串口通信,完成固件传输。最后提供了Bootloader与APP的HEX文件合并方法,便于量产烧录,显著提升产品可维护性。

earth的博客 450

mysql批量插入性能优化:executeBatch如何通过rewriteBatchedStatements参数逆袭

本文主要介绍在采用executeBatch进行mysql批量数据插入时,通过在mysql连接信息中添加`rewriteBatchedStatements=true`使得执行效率大幅提升。

弹指天下 1万+

mysql批量快速插入数据

首先是后端循环插入数据库(不推荐) 首先是慢的由于需要插入大量数据库,很慢的方法 插入方式为程序遍历循环逐条插入。在mysql上检测插入一条的速度在0.02s到0.04s之间。 所以逐条插入的速度是0.03*30000条的速度是15分钟左右。 所以逐条插入是没法优化的。然后去查询优化方式。发现用批量插入的方法可以提高很大速度。 将30000条数据的插入速度提升到1-2分钟左右 @Test public void insertCjmxb() { Cjmxb cjmxb =

Y_R_Q的博客 1490

mybatis-plus优化-rewriteBatchedStatements飞速提升

深入了解rewriteBatchedStatements优化过程

常有理爱摸鱼 6699

Mysql使用PreparedStatement的批量插入优化

背景 上W级别的单表数据,要实现快速插入 使用executeBatch 优化 原实现 PreparedStatement cmd = connection .prepareStatement("insert into test values(?,?)"); for (int i = 0; i < 10000; i++) { ...

奔跑的五花肉 3228

浅谈python反序列化漏洞

0x01 python序列化与反序列化 Python 的序列化和反序列化是将一个类对象向字节流转化从而进行存储和传输,然后使用的时候再将字节流转化回原始的对象的一个过程。python中的序列化操作是通过pickle模块,而该模块主要包含l dumps将dict转化为str格式,loads将str格式转化为dict格式。 dump和load与文件操作结合起来, pickle.dump(obj, f...

Lethe's Blog 3219

(转)MySQL批量插入处理之提高速度

【转载原因:亲测提升了100倍左右】 【转载原文:https://blog.youkuaiyun.com/tolcf/article/details/52102849#】 这是我转载的,但是我亲测了,好用!我的问题这个方法解决了!! 昨天研究了一下mysql的批处理,最初发现很慢 10000条 每次1000 243秒 50000条 每次500条 1295秒 代码如下: package main; import java.sql.*; public class JdbcS...

小蚯蚓的博客 1471

别光看Demo了!用UE5 Lyra框架快速搭建你的多人对战游戏原型(含完整配置流程)

本文详细介绍了如何利用UE5 Lyra框架快速搭建多人对战游戏原型,包含完整的配置流程和实战案例。Lyra作为可直接二次开发的游戏模板,内置了GAS技能系统、Enhanced Input输入控制等核心功能,大幅缩短开发周期。通过替换角色模型、调整武器数值和配置新地图规则,开发者可在48小时内完成科幻团队竞技游戏原型的搭建。

weixin_28717411的博客 455

提高mybatisplus 批量插入musql 速度的解决方案

解决方案: 1.mybatis plus使用批量插入的方式 2.mysql层面,需要在连接地址上加上下面的参数rewriteBatchedStatements=true 效果明显,亲测有效. 背景 在使用mybatis plus整合mysql的时候,需要将数据批量插入mysql 使用的过mybatis plus的同学都应该知道mbp的封装已经很好了,给我们提供了批量插入的方法: public interface IService<T> { //批量插入 default boolea

盛夏光年-进阶修炼池 662

基于STM32与MPU6050的实时姿态检测系统设计与实现(源码+硬件解析)

本文详细介绍了基于STM32单片机与MPU6050传感器的实时姿态检测系统设计与实现。通过硬件解析、传感器校准、卡尔曼滤波算法和欧拉角计算,实现高精度姿态检测。提供完整源码和调试技巧,适用于无人机、平衡车等嵌入式开发项目,解决噪声干扰和数据漂移等常见问题。

jupi8的博客 493

安装Anaconda和Labelme的教程

1 登录Anaconda官网,选择Download https://www.anaconda.com/distribution/ 2 选择你想下载的Python版本,选择你的操作系统和位数,然后点击Download按钮就开始下载了 3 开始安装 下面两个框框都勾选 点击next,等待安装成功 打开Anaconda Navigator 点击红色圈圈的按钮 在cmd中输入 (1)创建虚拟环境 conda create -n labelme python=3.6 (2)激活虚拟环境 conda activa

qq_42178122的博客 3807

mybatis&mybatis-plus 批量插入数据,批处理提升Mysql数据库插入速度

mysql数据库批量插入、批处理插入数据、提升数据插入速度 rewriteBatchedStatements=true

weixin_38680917的博客 1396

深入瑞芯微ISP生态:手把手配置RK3588上的RKAIQ Server并与Windows端RKISP Tuner联调

本文详细介绍了如何在RK3588平台上配置RKAIQ Server并与Windows端的RKISP Tuner进行联调,以实现高效的ISP调优。从环境准备、服务部署到实战调试,涵盖了IMX415相机适配等关键步骤,帮助开发者快速掌握瑞芯微ISP生态的核心技术。

weixin_32447969的博客 668

mysql 批量查询、批量插入优化

这段时间一直在参与产品库的设计和实现,中间和mysql的恩恩怨怨给广大喜欢交流学习的网友们,提供一些借鉴的机会。首先从mysql的批量插入开始吧。 1.mysql批量插入优化。 一直自认为对sql语句的数量使用,完全绝对的低估了现实问题的难度。100w的产品基础数据插入用掉了10个小时的时间。很挫…第一批实验数据100w插入后,让我久久不能释怀,这10个小时让我很纠结。 找原因吧,之前先入为

ptzrbin的专栏 9935

uniapp 记录运动轨迹 开发_智能手环穿戴设备APP开发解决方案

智能手环是一种穿戴式智能设备,是目前备受关注的科技产品。目前智能手环具有的功能有记录日常生活中的运动数据、移动轨迹,定位等,有些还可以进行睡眠质量的检测,并将这些数据传送至移动端如手机、平板等,可对数据进行分析,指导健康生活的作用。而智能手环开发方案就是将这些功能实现,将算法烧录到主控板上。智能手环都有哪些功能  1、记录运动数据  对于喜欢健身的用户来说,智能手环记录的运动数据功能...

weixin_39678493的博客 1764

小红书图文笔记图像批量爬取:Python爬虫实战与反反爬策略全解析

在当今社交媒体盛行的时代,小红书作为中国领先的生活方式分享平台,积累了海量的优质图文内容。对于数据分析师、市场研究人员或内容创作者来说,能够高效获取这些数据具有重要意义。本文将详细介绍如何使用Python构建一个高效、稳定的小红书图文笔记图像批量爬取工具,涵盖最新技术栈和反反爬策略。本文详细介绍了如何使用Python构建一个高效、稳定的小红书图文笔记图像批量爬取系统。通过结合Playwright、aiohttp等现代工具,实现了从列表页采集到图片下载的完整流程。

2201_76125261的博客 2362

Java实现数据批量导入数据库(优化速度-2种方法)

目录程序结构 连接数据程序 批量处理的两种方式 main方法 使用JDBC连接MySQL数据库进行数据插入的时候,经常会遇到数据量较大,插入数据库较慢,如何进行优化,加快导入数据库的速度,批量处理呢?以下程序提供了两种方法。程序结构连接数据程序package db; import java.sql.Connection; import java.sql.DriverManager; public c

qy20115549的博客 5万+

【图像超分】论文精读:Accelerating the Super-Resolution Convolutional Neural Network(FSRCNN)

作为应用于图像超分辨率 (SR) 的成功深度模型,超分辨率卷积神经网络 (SRCNN) [1,2] 在速度和恢复质量方面都比以前的手工制作的模型表现出更好的性能。然而,高计算成本仍然阻碍了它的实际使用,这需要实时性能(24 fps)。在本文中,我们旨在加速当前的 SRCNN,并提出了一种紧凑的沙漏形 CNN 结构,以实现更快和更好的 SR。我们从两个方面重新设计了SRCNN结构。首先,我们在网络末端引入了一个反卷积层,然后将映射直接从原始低分辨率图像(无插值)学习到高分辨率图像。其次,我们通过在映射之前缩小

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 1万+

MySQL千万级数据进行插入,基础数据3千万,插入1千万数据时间约为4.7分钟,10个线程同时插入

先看下数据,以及日志: 使用多线程,每条线程处理数据100万条,每次插入携带数据7万条 数据库基数为0,插入1000万条数据,时间为311957毫秒,也就是311.957秒,约为5分钟2秒 数据库基础数据为2000万条数据,插入1000万条数据,时间为302545毫秒,也就是502.545秒。约5分钟1秒 1000万条数据日志 ===================&gt...

一起记录GIS学习 3982

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

mysql编程笔记:百万级数据插入速度提高方法

当mysql大批量插入数据的时候就会变的非常慢,mysql提高insert into 插入速度的方法有三种: 第一种插入提速方法: 如果数据库中的数据已经很多(几百万条),那么可以加大mysql配置中的 bulk_insert_buffer_size,这个参数默认为8M bulk_insert_buffer_size=100M 第二种mysql插入提速方法: 改写所有 insert into 语句为insertdelayed into 这个insert delayed不同之处在于...

C语言C++学习俱乐部:765860056 1033

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

数据库大批量SQL插入的性能优化

对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长。特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久。因此,优化数据库插入性能是很有意义的。 经过对MySQL InnoDB的一些性能测试,发现一些可以提高insert效率的方法,供大家参考参考。 1、一条SQL语句插入多条数据 常用的插入语句如: INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VA

ct_bao的博客 690

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Python 中 sqlite3 使用 executemany 批量插入数据

千言万语,不如一个 demo 来得深沉。就目前我所知道的, Python 里边 MySQL 和 sqlite 都是可以使用 executemany 批量插入大量数据的,而且效率基本上是普通插入的数量级提升。 使用 executemany 的好处 效率高 我自己测试过,同样的一万多条数据,普通插入用时 54.5 秒,使用 executemany 用时 0.22 秒。效率这玩意儿,我就不多赘述了。 不过 sql 稍微有点区别的是,sqlite 是使用的 ? 作为占位符,而不是 %s,%d 之类的哟!正确

Looking的网页备忘录和个人知识库 1万+

mysql 批量提交执行速度_mysql 如何提高批量导入的速度

mysql数据库导入数据的速度:0. 最快的当然是直接 copy 数据库表的数据文件(版本和平台最好要相同或相似);1. 设置 innodb_flush_log_at_trx_commit=0 ,相对于 innodb_flush_log_at_trx_commit= 1 可以十分明显的提升导入速度;2. 使用 load data local infile 提速明显;3. 修改参数bulk_i...

weixin_26795171的博客 431

mysql批量插入跟更新_mysql批量插入(insert)与批量更新(update)的例子

本节内容:mysql数据库中批量插入与批量更新数据。在数据库插入或更新大量数据时,批量处理比挨条处理要快许多。以下介绍insert 和 update 批量处理数据的方法。insert 的语法为insert into table (id,value) values (1,2)。当有成千上万条数据要插入时,可以这样:insert into table (id,value) values(1,2),(2...

weixin_36221948的博客 1462

mysql sql 批量update_mysql批量插入(insert)与批量更新(update)的例子

本节内容:mysql数据库中批量插入与批量更新数据。在数据库插入或更新大量数据时,批量处理比挨条处理要快许多。以下介绍insert 和 update 批量处理数据的方法。insert 的语法为insert into table (id,value) values (1,2)。当有成千上万条数据要插入时,可以这样:insert into table (id,value) values(1,2),(2...

weixin_31556767的博客 1766
上一篇: 启动zookeeper报错:... /usr/local/zookeeper-3.4.8/bin/zkServer.sh: line 140: ./zookeeper.out: Permis
下一篇: Exception in thread "main" java.sql.SQLException: Before start of result set异常处理方法
那记忆微凉
博客等级 码龄9年 412粉丝 387原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值