Spring Batch JPA Bulk Insert在使用GenerationType.IDENTITY时性能下降 [英] Spring Batch JPA Bulk Insert eats performance when using GenerationType.IDENTITY

查看:5
本文介绍了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=1000chunkSize=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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆