【发布时间】:2019-01-08 10:24:02
【问题描述】:
我必须改进一个非常慢的代码的性能,而且我对 Hibernate 还是很陌生。我仔细研究了代码并得出结论,问题在于它有大量要加载的实体和update/insert。要将算法转换为更易于理解的示例,假设我们有一个这样的算法:
for each competitionToSave in competitionsToSave
competition <- load a Competition by competitionToSave from database
winner <- load Person by competitionToSave.personID
do some preprocessing
if (newCompetition) then
insert competition
else
update competition
end if
end for
当competitionToSave 中有很多competitions 时,这个算法当然是有问题的。所以,我的计划是选择所有涉及两个数据库请求最多的competitions 和winners,预处理数据,这将加快读取速度,但更重要的是,确保我将通过insert/@ 保存987654331@ 批次 100 competitions 而不是单独保存。由于我对 Hibernate 很陌生,所以我咨询了documentation 并找到了以下示例:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
但是,我不确定我是否理解正确。关于方法.save()我看了:
持久化给定的瞬态实例,首先分配一个生成的 标识符。 (或者使用标识符属性的当前值,如果 使用分配的生成器。)此操作级联到关联 如果关联使用 cascade="save-update" 映射,则实例。
但我不清楚是否每个save 都会向数据库发送请求。如果我假设在取自文档session.save(customer) 的示例中将对象的修改保存在Session 而不 向数据库发送请求然后在每20 个项目上@ 987654337@向数据库发送请求,session.clear()删除Session的缓存?
【问题讨论】:
-
据我所知hibernate,你的想法是对的。我刚刚从事一个项目,必须保存/更新 250 万条记录。这个项目告诉我hibernate对大量数据使用废话。最后,我使用了一个只有 1 事务的存储过程。如果您真的想加快休眠速度,请研究批处理以及适当的事务管理
-
@XtremeBaumer 出色的评论。阅读文档时,我考虑过这种可能性,但在我的具体情况下,这似乎是一种矫枉过正。客户每天等待 10 分钟。我估计我想要生成的理想代码大约快 200 倍,这意味着我们将有 600 000 / 200 毫秒,也就是 3 秒。这是可以接受的。
标签: java hibernate batch-updates batch-insert