我必须提高非常慢的代码的性能,而我对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
当competition
中有许多competitionToSave
时,此算法当然会出现问题。因此,我的计划是选择与两个数据库请求有关的所有competition
和winner
最多的预处理数据,这将加快读取速度,但更重要的是,确保我将通过{ {1}} / insert
批次的100 update
而不是分别保存。由于我刚接触Hibernate,因此我咨询了documentation并找到了以下示例:
competition
但是,我不确定我是否正确理解。关于方法.save(),我读到:
坚持给定的瞬态实例,首先分配一个生成的 标识符。 (或者使用标识符属性的当前值,如果 使用分配的生成器。)此操作级联到 关联是通过cascade =“ save-update”映射的实例。
但是我不清楚是否每个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
中获取的示例中,将对象的修改保存到session.save(customer)
中,而没有向数据库发送请求,然后在每次发送Session
将第20个项目发送到数据库,而session.flush()
删除session.clear()
的缓存?
答案 0 :(得分:1)
您的假设是正确的,尽管插入操作将被一次触发:
$("#fileSelect").empty();
$("#fileSelect").select2({data: data});
您可以尝试利用批量插入功能进一步提高性能。
有一个休眠属性,您可以将其定义为休眠insert into Customer(id , name) values (1, 'na1');
insert into Customer(id , name) values (2, 'na2');
insert into Customer(id , name) values (3, 'na3');
的属性之一:
SessionFactory
使用此批处理设置,每次冲洗后应该具有如下输出:
<property name="jdbc.batch_size">20</property>
一次插入而不是二十次。