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 提高批量插入的性能的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA HIbernate 批量插入速度较慢