![](/img/trans.png)
[英]Hibernate doesn't insert child entities: Hibernate: select nextval ('hibernate_sequence')
[英]Spring JPA - Hibernate: Batch insert execute too much select nextval (‘sequence’)
現在我正在嘗試提高我的 web 應用程序的性能,我使用 spring JPA 2.3.0- Hibernate 5.4.15.Final,Postgres 12 並通過@Transaction 管理事務。 web app部署在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
好像Hibernate可以批量插入,問題是Hibernate多次執行select nextval ('students_id_seq')
。 如果實體列表有30條,Hibernate執行30次select nextval
,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.AUTO
或GenerationType.SEQUENCE
with allocationSize = 1
:
我的問題是,是否有批量插入但不執行許多select nextval
查詢? 類似GenerationType.IDENTITY
的東西,不執行select nextval
,只是批量插入,ID 將按數據庫中的順序處理。
當我使用GenerationType.SEQUENCE
和allocationSize=1
(GenerationType.AUTO)
進行測試時,應用程序執行了過多的select nextval
查詢,我認為它甚至比 IDENTITY 策略更糟糕。 而且由於某些原因,我不想使用allocationSize
,它可能會導致在運行 insert query manual 或 migrate data 時或其他一些情況下出現重復的主鍵錯誤。
經過一些研究,我找到了一種獲取序列值列表的方法:
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;
我會說我在這一點上有一些經驗。 我正在插入超過 128,000 條記錄。 而我的目標是提高這樣做的耗時。 我會嘗試將案例總結如下:
該代碼沒有使用任何 persist() 或 save() 方法。 這些記錄是在@Transactionl 方法退出時保存的
我正在使用 hibernate 下面的批量插入是配置 map 中的設置
spring.jpa.properties.hibernate.jdbc.batch_size: "40" spring.jpa.properties.hibernate.order_inserts: "true" spring.jpa.properties.hibernate.order_updates: "true" spring.main.allow-bean-definition-overriding: "true"
我修改了實體 ID 配置中的分配大小,如下所示:
@ID
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator ="mappingentry_sql_generator")
@SequenceGenerator(name = "mappingentry_sql_generator", sequenceName ="mappingentry_id_seq", allocationSize = 40)
private Long id;
注意:我將序列生成器中的“allocationSize”設置為等於設置中的“batch_size”值
進行這些更改后,時間從 55 秒減少到 20 秒,這是一個很大的影響
我唯一不明白的是,當我檢查序列生成的 id 列的值時,我沒有發現任何值差距。 每個 ID 值都超過前一個值 1,而不是 40。這就是我目前想要了解的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.