Spring Batch JPA Bulk Insert在使用GenerationType.IDENTITY时性能下降 [英] Spring Batch JPA Bulk Insert eats performance when using GenerationType.IDENTITY
本文介绍了Spring Batch JPA Bulk Insert在使用GenerationType.IDENTITY时性能下降的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
Spring Boot and Spring Batch and JPA
将数据从一个数据库加载到另一个数据库。在单个批处理作业中,我创建了10 steps
以按顺序运行步骤,每个步骤读取几乎1 millions
个记录(我不能并行运行,因为我没有并行加载数据)。
我使用了GenerationType.IDENTITY
,因为这个批处理作业花费了大量时间,所以看起来像是。如果我说加载100 records
,则需要2 min
。目标Postgres database
已由DBA实现sequences
,我们必须遵循这些操作,但它会消耗所有性能。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "EMP_ID", nullable = false, updatable = false, insertable = false)
private Long id;
如何提高此批处理作业的性能?
我还保留了spring.jpa.properties.hibernate.jdbc.batch_size=1000
和chunkSize=1000
。
推荐答案
如果实体正在使用IDENTITY
生成其ID(在here处的文档中也有提到),则休眠无法批量插入实体。
所以您必须改为使用SEQUENCE
来生成ID。根据this,选择使用pooled或pooled-lo算法从序列中获取新的ID,以减少获取ID的往返次数,从而进一步提高性能。
因此ID映射如下:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="foo_sequence")
@SequenceGenerator(name="emp_sequence", sequenceName = "emp_id_seq", allocationSize = 100)
private Long id;
和休眠设置:
spring.jpa.properties.hibernate.order_inserts = true
spring.jpa.properties.hibernate.order_updates = true
spring.jpa.properties.hibernate.jdbc.batch_size = 1000
spring.jpa.properties.hibernate.jdbc.batch_versioned_data = true
# For using "pool-lo" optimiser for generating ID when using JPA @SequenceGenerator
spring.jpa.properties.hibernate.hibernate.id.optimizer.pooled.preferred = pooled-lo
还必须确保PostreSQL中对应的ID序列与@SequenceGenerator
中的配置对齐:
alter sequence emp_id_seq increment by 100;
另一个技巧是在JDBC连接字符串中添加reWriteBatchedInserts=true
,这将使docs中所说的性能提高2-3倍。
这篇关于Spring Batch JPA Bulk Insert在使用GenerationType.IDENTITY时性能下降的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文