gpt4 book ai didi

使用 GenerationType.IDENTITY 时,Spring Batch JPA Bulk Insert 会降低性能

转载 作者:行者123 更新时间:2023-12-05 01:12:12 37 4
gpt4 key购买 nike

我正在使用 Spring Boot、Spring Batch 和 JPA 将数据从一个数据库加载到另一个数据库。在单个批处理作业中,我创建了 10 个步骤 以按顺序运行步骤,每个步骤读取近 100 万 记录(我不能并行运行,因为数据我没有并行加载)。

我使用了 GenerationType.IDENTITY 并且看起来像因为这个批处理作业占用了大量时间。如果我说要加载 100 条记录,它需要 2 分钟。目标 Postgres 数据库 具有由 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 的文档中也提到),Hibernate 无法批量插入实体。

因此您必须改为使用SEQUENCE 来生成ID。并根据this ,选择使用“pooled”或“pooled-lo”算法从序列中获取新 ID,以通过减少获取 ID 的往返次数来进一步提高性能。

所以 ID 映射看起来像:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="emp_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.id.optimizer.pooled.preferred = pooled-lo

此外,您必须确保 PostreSQL 中相应的 ID 序列与 @SequenceGenerator 中的配置对齐:

alter sequence emp_id_seq increment by 100;

另一个技巧是在 JDBC 连接字符串中添加 reWriteBatchedInserts=true,这将提供 2-3 倍的性能提升,如 docs 中所述.

关于使用 GenerationType.IDENTITY 时,Spring Batch JPA Bulk Insert 会降低性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62411431/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com