【问题标题】:how to increase the performance of bulk inserts using session factory如何使用会话工厂提高批量插入的性能
【发布时间】:2012-11-26 05:07:48
【问题描述】:

我正在使用 jpa 和使用 seam 的 hibernate。一次需要插入 200,000 条记录。

这是我的代码:

hibernate.cfg.xml

<hibernate-configuration>
 <session-factory name="java:/mobeeSessionFactory">
  <property name="hibernate.connection.pool_size">10</property>
  <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
  <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:mobee</property>
  <property name="hibernate.connection.username">mobeemigrate</property>
  <property name="hibernate.connection.password">mobeemigrate</property>
  <property name="hibernate.show_sql">false</property>
  <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
  <property name="hibernate.format_sql">false</property>
  <property name="hibernate.hbm2ddl.auto">update</property>
  <property name="hibernate.session_factory_name">java:/mobeeSessionFactory</property>
  <property name="hibernate.connection.datasource">mobeeadminDataSource</property>
  <property name="hibernate.jdbc.batch_size">10000</property>
  <property name="hibernate.cache.use_first_level_cache">true</property>
  <property name="hibernate.cache.use_second_level_cache">false</property>
  <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
  <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
  <property name="hibernate.transaction.auto_close_session">false</property>
  <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
  <property name="hibernate.transaction.flush_before_completion">true</property>

  <!-- Here are the mappings -->
  <mapping package="com.manam.mobee.persist.entity"/>
  <mapping class="com.manam.mobee.persist.entity.TempCustomers"/>
  <mapping class="com.manam.mobee.persist.entity.TempAccounts"/>
 </session-factory>

组件.xml

<persistence:hibernate-session-factory name="hibernateSessionFactory" cfg-resource-name="hibernate.cfg.xml"/>
    <persistence:managed-hibernate-session name="session" 
                 auto-create="true"
     session-factory-jndi-name="java:/mobeeSessionFactory"/>

示例代码:

 Session session =hibernateSessionFactory.openSession();
             Transaction tx = session.beginTransaction();

   for(int i=0;i<doTempAccounts.size();i++){

     try {
    TempAccounts temp=new TempAccounts();

    BeanUtils.copyProperties(temp, doTempAccounts.get(i));

    session.save(temp);

    if ( i % 10000 == 0 ) { //10000, same as the JDBC batch size
     //flush a batch of inserts and release memory:
    log.info("********** Batch Updates**********");
    session.flush();
    session.clear();
     }
     }
     }
    tx.commit();
    session.close();

上面的代码可以运行,但是插入 200,000 条记录大约需要 10 分钟。我的代码中是否有任何配置可以提高批量插入的性能?

在上面的代码中,我每 10000 条记录执行一次 session.flush(),但不是每次都插入数据库。你能解释一下如何对 db 执行批量插入吗?

【问题讨论】:

  • 查看无状态会话以进行批量操作
  • @Affe Thanx 回复,我会通过它,我有一个疑问在这个会话中我将 db 刷新到每 10000 条记录中,但为什么它没有每次都插入到 db 中?

标签: java hibernate session seam


【解决方案1】:

在上面的代码中,我每 10000 条记录执行一次 session.flush(),但不是每次都插入数据库。

我认为您的意思是在您到达终点之前,这些记录似乎并不存在;即它们不会出现在不同事务中的查询中。

如果这就是你的意思,那么解释很简单。您正在单个事务中进行插入,并且记录仅在事务提交时才可见......最后。如果您需要更快地看到插入,请尝试将插入拆分为多个事务


您还应该阅读有关批处理操作的 Hibernate 文档 - http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html。我注意到它说 合理 批量大小是 20 到 50 ...而不是 10000。它还提到了直接使用 SQL 进行批量数据操作的方法和StatelessSession

这是另一个特定于插入的资源,包括StatelessSession 的插入:http://javainnovations.blogspot.com.au/2008/07/batch-insertion-in-hibernate.html

【讨论】:

    【解决方案2】:

    查看 StatelessSession 以及如何使用它将项目插入数据库。当被问到这个问题时,这似乎是答案,我个人只是用它在大约 15 秒内完成了 15 分钟的工作。它并不适合所有场景,但如果适合,它会很好用。

    【讨论】:

    • thanx 回复 你能告诉我如何使用 StatelesSession 插入记录吗?因为我在 StatelessSession 中找不到保存方法..
    • @nag - 阅读我的答案中的链接。它有 StatelessSession 的示例代码。
    • @Steohen 我在那个 StatelessSession 中看到了那个例子,他们从 session.getNamedQuery 获取记录,在我的 senario 中从 .csv 文件中获取数据并存储到 arrayList。我如何使用 StatelessSession 接口来昆虫 arrayList 数据
    【解决方案3】:

    您几乎可以像在 SQL 中那样做。请看以下 HQL 示例:

    insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...
    

    参考:http://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch04.html#d0e2184

    【讨论】:

      猜你喜欢
      • 2019-12-07
      • 1970-01-01
      • 2018-11-02
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-08
      相关资源
      最近更新 更多