JPA 2.0:如何通过 JPA 提高批量插入的性能

Posted

技术标签:

【中文标题】JPA 2.0:如何通过 JPA 提高批量插入的性能【英文标题】:JPA 2.0: How to improve performance on bulk insertion through JPA 【发布时间】:2015-08-18 08:05:03 【问题描述】:

例子:

我有三个表:位置、部门、员工

现在让我们说位置和部门是已经拥有完整数据的主表。 现在我需要通过 JPA 插入 1000 个员工列表。 我也与 Employee Table 中的 Location 和部门有关系。

所以现在在 Employee 中插入条目,按照我正在做的:

for loop...1000
 Employee e = new Employee();
 e.setId(12);
 e.setEmpname("ABC");
 Location l = null;
 l = em.find(Location.class, 234);
 e.setLocation(l);
  Department d = null;
 d = em.find(Department.class, 111);
 e.setDepartment(d);
 em.persist(e);
loop ends...

将数据加载到数据库需要一些时间。它是通过 JPA 插入数据的唯一方法吗,因为它会降低性能。 我不想使用本机查询。 请建议是否有人有更好的方法来提高效率。

【问题讨论】:

在 x 次持久化之间进行刷新和清除。否则它会因为脏检查而变得越来越慢。 【参考方案1】:

JPA 2.0 不提供对批量插入的特定支持。保持在 JPA 习语内,您可以这样做:

EntityManager em = ...;
EntityTransaction tx = em.getTransaction();
tx.begin();

for (int i = 0; i < 100000; i++) 
    Employee e = new Employee();
    // setup entity
    em.persist(e);
    if ((i > 0) && (i % 20 == 0))  // Flush in batches of 20 to keep caches from bogging.
        em.flush();
        em.clear();
    


tx.commit();
session.close();

或者,您可以使用 em.createNativeQuery() 并触发原生 SQL 批量插入。

根据您使用的特定数据库和 ORM,还有其他几种可能性。例如,EclipseLink (http://java-persistence-performance.blogspot.com/2011/06/how-to-improve-jpa-performance-by-1825.html) 或参数化 (http://java-persistence-performance.blogspot.com/2013/05/batch-writing-and-dynamic-vs.html) 有一些技巧。

可以在此处找到特定于 Hibernate 的演练:http://korhner.github.io/hibernate/hibernate-performance-traps-part-2/

【讨论】:

我有 70.000 行要提交。这条评论从 10 分钟缩短到 35 秒

以上是关于JPA 2.0:如何通过 JPA 提高批量插入的性能的主要内容,如果未能解决你的问题,请参考以下文章

JPA SQL Server 批量插入

Spring Data JPA HIbernate 批量插入速度较慢

Spring JPA - Hibernate:批量插入执行太多选择 nextval('sequence')

如何在 JPA 和自定义 UUID 标识符中实现批量插入

如何在 JPA 中进行 BATCH 插入?

JPA/Hibernate 批量(批量)插入