java - hibernate 性能问题,坚持一个接一个还是批量?

标签 java database hibernate persistence

我有一个约 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/

相关文章:

Java main 未运行 <已终止>

java - 这个反向字符串算法的运行时间是多少?

database - 根据与 Laravel 和 Eloquent 的关系进行计数和排序

java - 为什么这个使用 Hibernate `Set` 字段的示例没有在数据库表中声明外键?

java - n 个字符串的交集

java - 告诉低级对象使用哪些工厂的好方法是什么?

database - Access 2000 数据库安全

java - 如何在关闭 Java 连接之前返回 ResultSet

java - iBatis 是否有类似 Hibernate 的 `hbm2ddl` 的内存数据库集成测试?

java - "org.hibernate.PersistentObjectException: detached entity passed to persist"当我尝试在数据库中插入数据时