【问题标题】:OpenJPA merging/persisting is very slowOpenJPA 合并/持久化非常慢
【发布时间】:2012-06-15 04:28:37
【问题描述】:

我在 WebSphere Application Server 8 上使用 OpenJPA 2.2.0 和 MySQL 5.0 DB。

我有一个要合并到数据库中的对象列表。

就像:

for (Object ob : list) {
            Long start = Calendar.getInstance().getTimeInMillis();
            em = factory.createEntityManager();
            em.getTransaction().begin();

            em.merge(ob);

            em.getTransaction().commit();
            em.close();
            Long end = Calendar.getInstance().getTimeInMillis();
            Long diff = end - start;
            LOGGER.info("Time: " + diff);
        }

当我运行这个循环时,我需要大约 300-600 毫秒来合并一个对象。当我删除“em.merge(ob);”行时那么我需要“0”毫秒来迭代 1 个列表对象。

所以我的问题是:我能做些什么来缩短合并一个对象的时间?

谢谢!

【问题讨论】:

  • 开启 SQL 日志记录,查看生成了哪些请求,查看哪些请求需要时间以及原因。

标签: java mysql performance openjpa


【解决方案1】:

您可以尝试在迭代之前启动事务,然后在单个事务中提交它。所以,基本上你正在创建一个将在提交时合并/持久化的批处理。

此外,您可以限制一次要处理的批处理中的对象数量,并且可以将更改显式刷新到数据库中。

在这里,您正在启动一个事务并在每次迭代中提交它,并且每次都创建/关闭实体管理器,这将影响大量数据的性能。

这将类似于下面的代码。

em = factory.createEntityManager();
em.getTransaction().begin();
int i = 0;

   for (Object ob : list) {
       Long start = Calendar.getInstance().getTimeInMillis();

       em.merge(ob);

       Long end = Calendar.getInstance().getTimeInMillis();
       Long diff = end - start;
       LOGGER.info("Time: " + diff);

       /*BATCH_SIZE is the number of entities 
            that will be persisted/merged at once */

       if(i%BATCH_SIZE == 0){    
           em.flush();
           em.clear(); 
       }

       i++;
   }

em.getTransaction().commit();
em.close();

在这里,如果任何对象无法持久/合并,您还可以回滚整个事务。

【讨论】:

  • 谢谢,我以前试过这个,但是我拥有的对象越多,合并的速度就越慢,我的列表中大约有 4000 个对象
  • @veote 正如我已经提到的,您可以明确限制实体的数量。在代码中添加批处理逻辑,您可以在其中指定适当的批处理大小(例如取 100,然后对 100 个实体的更改将立即一次反映在数据库中),参考代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
  • 1970-01-01
  • 2012-11-14
相关资源
最近更新 更多