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

Hibernate 批量插入速度慢的原因和解决方法

由于业务需要一次性连续写入超过10k条以上的新数据,当对象超过10个成员变量以后,整个写入过程居然需要长达35秒,这个速度是不能接受的,故此研究了一下怎么开启Hibernate批量写入的功能。

我这边使用的是Hibernate 5.6.15

在网上找了一些答案,都提到了Hibernate自带批量写入的功能,通过在

“hibernate.cfg.xml”的文件中增加一个特征

<property name="hibernate.jdbc.batch_size">50</property>

必须在connection.url 的后面增加一个参数?rewriteBatchedStatements=true&amp;

我的配置:

<!--数据源配置--><property name="connection.username">root</property><property name="connection.password">12345678</property><property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property><property name="connection.url">jdbc:mysql://localhost:3306/hibernate_test?rewriteBatchedStatements=true&amp;userUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC</property><!--批量处理配置--><property name="hibernate.jdbc.batch_size">50</property>

我这边实测,发现速度并没有变快,然后使用WireShake监听了一下程序对MYSQL的网络请求,发现如果写入1W条数据,那么就会发生2W多次的TCP链接,每次链接传输的数据内容虽然加密了,但是内容并不多,明显不是批量发送的多个条目,而是一个一个发送的。

这一点让我觉得很奇怪,明明启用了Hibernate的批量写入功能,为什么还是一条一条写入的?

网上的大牛们指出,如果写入的对象的ID采用了Hibernate自增策略,那么批量写入功能就会自动关闭,因为自增的前提是获取到上次写入的对象得到的ID+1来实现的。

那么,既然知道写入慢的原因了,那么解决起来也就简单了。

首先删掉自增ID的策略,然后在代码中增加手动赋值ID的功能

        String hql = "from People order by id desc";//将当前数据库的数据采用ID倒序排列Query query = session.createQuery(hql);query.setMaxResults(1);//读取第一个数据List<People> list = query.list();Integer lasstId = 0;if(list.size() == 0){//如果读取队列长度为0.说明这是一个空表,ID赋值为1lasstId = 1;}else{//获取最后一个ID值lasstId = list.get(0).getId()+1;}List<People> peopleList = new ArrayList<>();for(int i=0;i<10000;i++){People people = new People();people.setId(lasstId++);//每次赋值结束后自增1people.setName("测试"+i);people.setMoney(100*i);peopleList.add(people);}session.beginTransaction();for(int i=0;i<10000;i++){session.save(peopleList.get(i));}session.getTransaction().commit();session.close();

通过这种方式,就可以使用Hibernate的批量写入功能。

通过实际监听的结果,同样写入1W条数据,实际发生了800多次TCP链接

既然如此,我干脆把批量处理的SQL条数改成了10000条

<property name="hibernate.jdbc.batch_size">10000</property>

结果速度就更快了,而且TCP只发生了105次连接

如果实际投入生产是不可以改成10000条保存一次的,因为这里使用的是Hibernate的一级缓存用于累积数据,如果你要保存的对象有很多成员变量,1W条数据很容易让缓存内存溢出,所以,针对每个人实际业务的情况酌情处理,即便每次只有50条,也相当于加速了50倍,也是很快啦。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 六、Selenium操作指南(二)
  • JavaEE第19节 用UDP套接字实现简单回显服务器
  • JVM学习《类加载运行-jvm内存模型》
  • EXO:StandardNode _process_tensor
  • Node.js中的SQLite库:安装、对比与选择指南
  • Datawhale X 李宏毅苹果书 AI夏令营 进阶 Task2-自适应学习率+分类
  • 100423. 求出数字答案 显示英文描述
  • Makefile入门
  • java之浅拷贝、深拷贝
  • vscode和edge浏览器等鼠标输入光标变透明
  • 单链表应用
  • 【Android】UI拓展之滑动菜单、悬浮按钮、CoordinatorLayout布局等
  • excel透视图、看板案例(超详细)
  • 保姆级Maven安装、配置、版本查询教程(包含配置本地仓库、阿里云私服、环境变量)
  • PWM(Pulse-width modulation)脉冲宽度调制
  • HTML-表单
  • java8 Stream Pipelines 浅析
  • React-flux杂记
  • React-redux的原理以及使用
  • Swift 中的尾递归和蹦床
  • Vue.js 移动端适配之 vw 解决方案
  • 成为一名优秀的Developer的书单
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 免费小说阅读小程序
  • 前端性能优化--懒加载和预加载
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • # 数仓建模:如何构建主题宽表模型?
  • #13 yum、编译安装与sed命令的使用
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (ZT)薛涌:谈贫说富
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (简单) HDU 2612 Find a way,BFS。
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (算法设计与分析)第一章算法概述-习题
  • (转)关于pipe()的详细解析
  • .gitignore文件_Git:.gitignore
  • .net SqlSugarHelper
  • .NET 的程序集加载上下文
  • .NET 分布式技术比较
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .Net多线程Threading相关详解
  • @AutoConfigurationPackage的使用
  • @Transactional事务注解内含乾坤?
  • [《百万宝贝》观后]To be or not to be?
  • [20170728]oracle保留字.txt
  • [240812] X-CMD 发布 v0.4.5:更新 gtb、cd、chat、hashdir 模块功能
  • [Android] Upload package to device fails #2720
  • [Android]使用Git将项目提交到GitHub
  • [bzoj4240] 有趣的家庭菜园
  • [CareerCup] 2.1 Remove Duplicates from Unsorted List 移除无序链表中的重复项
  • [hdu 4552] 怪盗基德的挑战书