Tu *_*oan 5 java spring hibernate batch-insert spring-data-jpa
现在我正在尝试增强 Web 应用程序的性能,我使用 spring JPA 2.3.0- Hibernate 5.4.15.Final、Postgres 12 并通过 @Transaction 管理事务。Web应用程序部署在aws beanstalk上,同时运行多个实例,但数据库实例不可扩展。我使用 bigSerial 类型作为表的 ID。
例如,我有一个 STUDENTS 表,ID 是 bigSerial 和一些其他列。我在使用时遇到问题
@GeneratedValue(strategy = GenerationType.IDENTITY)
,Hibernate在保存实体列表时无法批量插入。我尝试使用
@GeneratedValue(strategy = GenerationType.AUTO, generator = "students_id_seq")
@SequenceGenerator(name = "students_id_seq", sequenceName = "students_id_seq")
hibernate.id.new_generator_mappings=false
hibernate.jdbc.batch_size=10
hibernate.order_inserts=true
hibernate.order_updates=true
hibernate.batch_versioned_data=true
Run Code Online (Sandbox Code Playgroud)
看起来Hibernate可以批量插入,但问题是Hibernate执行了select nextval ('students_id_seq')多次。如果实体列表有30个项目,Hibernate会执行select nextval30次,批量插入查询则执行3次。
一些统计数据:
如果使用 GenerationType.IDENTITY
insert into ... : 执行一次insert into ... : 执行n次如果使用 GenerationType.SEQUENCE/ GenerationType.AUTO
select nextval ('students_id_seq'): 执行一次insert into ... : 执行一次select nextval ('students_id_seq'): 执行n次insert into ... :执行n/batch_size次总之,如果使用GenerationType.AUTOor GenerationType.SEQUENCEwith allocationSize = 1:
我的问题是,是否有批量插入但不执行多个select nextval查询的方法?像这样的东西GenerationType.IDENTITY,而不是执行select nextval,只是批量插入,并且ID将按数据库中的顺序处理。
当我使用GenerationType.SEQUENCEand进行测试时allocationSize=1 (GenerationType.AUTO),应用程序执行了太多select nextval查询,我认为它比 IDENTITY 策略还要糟糕。由于某些原因,我不想使用allocationSize,当手动运行插入查询或迁移数据或其他一些情况时,它可能会导致重复主键错误。
经过一番研究,我找到了一种获取序列值列表的方法:
select nextval ('students_id_seq') from generate_series(1,10);
我们可以用entityList.size()替换10,或者批量插入时entityList中没有ID的实体数量,只要够用即可,不要在ID之间造成太大的差距,但我不确定是否或不支持 Hibernate,如果支持,请分享给我参考文档。
谢谢
https://discourse.hibernate.org/t/batch-insert-execute-too-much-select-nextval-sequence/4232
您正在寻找的是用于 id 生成的HiLo 算法。
对于从序列生成的每个 id,它会在客户端上生成多个 id,而无需访问数据库。
您可以在实体上将其配置如下:
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hilo_sequence_generator")
@GenericGenerator(
name = "hilo_sequence_generator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@Parameter(name = "sequence_name", value = "hilo_seqeunce"),
@Parameter(name = "initial_value", value = "1"),
@Parameter(name = "increment_size", value = "3"),
@Parameter(name = "optimizer", value = "hilo")
})
@Id
private Long id;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4527 次 |
| 最近记录: |