休眠批量大小混乱

休眠批量大小混乱,第1张

休眠批量大小混乱

当您调用时

session.save()
,hibernate将生成一个INSERT SQL。该INSERT
SQL将附加在刷新期间(即
session.flush()
)发布给DB 。

在刷新过程中,如果

hibernate.jdbc.batch_size
将其设置为某个非零值,则Hibernate将使用JDBC2
API中引入的批处理功能向数据库发出批处理插入SQL。

例如,如果您有

save()
100条记录,而您的记录
hibernate.jdbc.batch_size
设置为50。在刷新期间,请不要发出以下SQL
100次:

insert into TableA (id , fields) values (1, 'val1');insert into TableA (id , fields) values (2, 'val2');insert into TableA (id , fields) values (3, 'val3');.........................insert into TableA (id , fields) values (100, 'val100');

Hiberate将它们分为50个批处理,并且仅向数据库发出2条SQL,如下所示:

insert into TableA (id , fields) values (1, 'val1') , (2, 'val2') ,(3, 'val3') ,(4, 'val4') ,......,(50, 'val50')insert into TableA (id , fields) values (51, 'val51') , (52, 'val52') ,(53, 'val53') ,(54, 'val54'),...... ,(100, 'val100')

请注意,如果插入表的主键为,则Hibernate将透明地禁用JDBC级别的插入批处理

GenerationType.Identity

从您的日志中:您

save()
只有一条记录,然后是
flush()
,因此对于每次刷新,仅要处理一条附加的INSERT
SQL。这就是Hibernate无法帮助您批量插入的原因,因为只有一个INSERT
SQL要处理。
save()
在调用之前,您应该最多保留一定数量的记录,
flush()
而不是
flush()
每次都调用
save()

批处理插入的最佳实践是这样的:

Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();for  ( int i=0; i<888888; i++ ) {  TableA record = new TableA();    record.setXXXX();    session.save(record)    if ( i % 50 == 0 ) { //50, same as the JDBC batch size        //flush a batch of inserts and release memory:        session.flush();        session.clear();    }}tx.commit();session.close();

您分批保存并刷新记录。在每个批处理的末尾,您应该清除持久性上下文以释放一些内存,以防止在将每个持久性对象放入第一级缓存(JVM的内存)中时导致内存耗尽。您也可以禁用二级缓存以减少不必要的开销。


参考:

  • Hibernate官方文档:第14章。批处理
  • 休眠批处理–为什么您可能不使用它。(即使您认为自己是)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5477847.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存