gpt4 book ai didi

java - Spring JPA- hibernate : Batch insert execute too much select nextval (‘sequence’ )

转载 作者:行者123 更新时间:2023-12-01 16:21:45 25 4
gpt4 key购买 nike

现在我正在尝试增强 Web 应用程序的性能,我使用 spring JPA 2.3.0- Hibernate 5.4.15.Final、Postgres 12 并通过 @Transaction 管理事务。 Web应用程序部署在aws beanstalk上,同时运行多个实例,但数据库实例不可扩展。我使用 bigSerial 类型作为表的 ID。

例如,我有一个 STUDENTS 表,ID 是 bigSerial 和一些其他列。我在使用时遇到问题

@GenerateValue(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

看起来 Hibernate 可以批量插入,但问题是 Hibernate 多次执行 select nextval ('students_id_seq') 。如果实体列表有 30 个项目,Hibernate 会执行 select nextval 30 次,批量插入查询则执行 3 次。

一些统计数据:

  • 如果使用 GenerationType.IDENTITY

    • 保存(实体):
      • 插入...:执行一次
    • saveAll(n 个实体)
      • 插入...:执行n次
  • 如果使用 GenerationType.SEQUENCE/GenerationType.AUTO

    • 保存(实体):
      • select nextval('students_id_seq'):执行一次
      • 插入...:执行一次
    • saveAll(n 个实体):
      • select nextval('students_id_seq'):执行n次
      • 插入...:执行n/batch_size次

总之,如果将 GenerationType.AUTOGenerationType.SEQUENCEallocationSize = 1 一起使用:

  • 插入一个实体时,应用程序执行次数增加100%查询(从 1 个插入查询仅增加到 2 个查询: selectnextval,并插入查询)
  • 批量插入时,如果batch_size = 10,应用程序增加10%以上
<小时/>

我的问题是,是否可以批量插入但不执行许多 select nextval 查询?类似于GenerationType.IDENTITY,不执行select nextval,只是批量插入,ID将按数据库中的顺序处理。

当我使用 GenerationType.SEQUENCEallocationSize=1 (GenerationType.AUTO) 进行测试时,应用程序执行了过多的 select nextval查询,我认为它比IDENTITY策略还要糟糕。由于某些原因,我不想使用 allocationSize,它可能会导致在手动运行插入查询或迁移数据或其他一些情况时出现重复主键错误。

经过一番研究,我找到了一种获取序列值列表的方法:

从generate_series(1,10)中选择nextval('students_id_seq');

我们可以用entityList.size()替换10,或者批量插入时entityList中没有ID的实体数量,够用即可,不要在ID之间造成太大的差距,但我不是确定是否支持Hibernate,如果支持,请分享给我引用文档。

谢谢

https://discourse.hibernate.org/t/batch-insert-execute-too-much-select-nextval-sequence/4232

最佳答案

您正在寻找的是HiLo algorithm用于生成 id。

对于从序列生成的每个 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;

关于java - Spring JPA- hibernate : Batch insert execute too much select nextval (‘sequence’ ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62254314/

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