我有一个约 6GB 的文本文件,我需要对其进行解析并稍后保存。通过“解析”,我从文件中读取一行(通常为 2000 个字符),从该行创建一个 Car-object,然后我坚持它。
我正在使用生产者消费者模式来解析和持久化,我想知道一次持久化一个对象(出于性能原因)或在一次提交中持久化 1000 个(或任何其他数量)对象是否有任何区别?
目前,我需要 >2 小时来持久化所有内容(300 万行),这对我来说看起来时间太多了(或者我可能是错的)。
目前我正在这样做:
public void persistCar(Car car) throws Exception
{
try
{
carDAO.beginTransaction(); //get hibernate session...
//do all save here.
carDAO.commitTransaction(); // commit the session
}catch(Exception e)
{
carDAO.rollback();
e.printStackTrace();
}
finally
{
carDAO.close();
}
}
在我进行任何设计更改之前,我想知道这种设计是否更好(或不更好)是否有原因,如果是这样,cars.size() 应该是多少?另外, session 的打开/关闭是否被认为是昂贵的?
public void persistCars(List<Car> cars) throws Exception
{
try
{
carDAO.beginTransaction(); //get hibernate session...
for (Car car : cars)
//do all save here.
carDAO.commitTransaction(); // commit the session
}catch(Exception e)
{
carDAO.rollback();
e.printStackTrace();
}
finally
{
carDAO.close();
}
}
最佳答案
传统上,hibernate 不能很好地处理批量插入。有一些方法可以将其优化到一定程度。
以 API Docs 中的这个例子为例,
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();
在上面的示例中,如果在插入 20 个条目后刷新 session ,这将使操作更快一些。
这里是interesting article讨论同样的事情。
我们已经成功地使用存储过程实现了批量插入的替代方法。在这种情况下,您会将参数作为“|”传递给 SP分隔列表,并将在 SP 中写入插入脚本。这里的代码可能看起来有点复杂,但非常有效。
关于java - hibernate 性能问题,坚持一个接一个还是批量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10274124/