Dre*_*208 6 hibernate jpa-2.0 spring-data-jpa
我最近制作了一个应用程序,该应用程序从一个数据库(旧版)中获取数据,然后将其放入另一个数据库中(新的开发数据库)。我发现困惑save并不总是奏效,而是奏效saveAndFlush了。该legacy数据库是在一个事务select和新的数据库是另一个deleteAll和save。
该应用程序运行非常缓慢saveAndFlush且易于理解,但save效果并不好。然后我决定使用,saveAll但是为每个表创建一个巨大列表的想法对我来说并不成立。所以我试图像这样调用车库收集:
productRepository.saveAll(productList);
productList.clear();
productList = null;
System.gc();
Run Code Online (Sandbox Code Playgroud)
然后我添加jdbc.batch_size到application.properties
logging.level.org.hibernate.SQL=info
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.generate-ddl = true
spring.jpa.properties.hibernate.jdbc.batch_size = 20
spring.jpa.properties.hibernate.order_inserts = true
spring.jpa.properties.hibernate.order_updates = true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data = true
Run Code Online (Sandbox Code Playgroud)
之前需要花两个小时才能运行,现在只有5分钟-巨大的性能提升。
现在我很困惑发生了什么。我读到的是“定期更新和关闭会话”。但是delete和saveAll是一次交易-因此对我来说这没有意义。
因此要弄清楚为什么有两个问题:
1)为什么不save总是有效但saveAndFlush会起作用?
2)有50个表,每个表有20,000行,每个表创建一个列表,然后saveAll清除该列表并建议进行垃圾回收。application.properties与方法相比,将上面的内容添加到导致应用程序极快#1。为什么?冬眠在做什么?是否定期更新和清除会话?
我认为正在发生的事情是第一层缓存保留了删除和插入操作,然后提交并希望将其刷新。显然我是错误的,或者至少不是完全正确的。
小智 -1
save和saveAndFlush之间的区别在于它们处理事务和将数据保存到数据库的方式。在保存的情况下,数据会保存到数据库,但可能不会立即刷新到数据库。实际的刷新可能稍后在提交当前事务时或刷新持久性上下文时发生。另一方面,saveAndFlush立即将数据保存到数据库并刷新更改。这意味着在方法调用返回之前数据保证保存在数据库中。
您在使用saveAll和垃圾收集以及批处理大小配置时观察到的显着性能提升可归因于 Hibernate 的批处理机制。当您使用saveAll时,Hibernate 通过将多个插入一起批处理来优化插入操作,减少数据库往返次数并提高性能。您配置的hibernate.jdbc.batch_size属性指定执行INSERT 或 UPDATE操作时将批量发送到数据库的语句数。这种批处理方法比每个实体的单独插入更有效,特别是在处理大量实体时。
通过显式清除productList并调用垃圾回收,您可以释放内存资源,这可以进一步提高性能,特别是在内存有限或处理大量数据的情况下。
总之,您观察到的性能改进是多种因素共同作用的结果:
使用saveAll可以进行批处理,从而减少数据库往返次数。
配置hibernate.jdbc.batch_size 属性可以通过将插入和更新操作批处理在一起来优化它们。清除productList并调用垃圾回收可以释放内存资源。
总的来说,在应用程序中处理大型数据集时,这些优化可以提高性能并更有效地利用资源。
| 归档时间: |
|
| 查看次数: |
1557 次 |
| 最近记录: |