高吞吐量数据导出
如果您只想导入数据而不进行任何处理或转换,则像PostgreSQL的COPY
工具是导入数据的最快方式。
批量处理
然而,如果您需要进行转换、数据聚合、现有数据和新数据之间的相关性/合并等操作,则需要应用程序级别的批处理。
在这种情况下,您需要定期执行flush-clear-commit
操作:
int entityCount = 50;
int batchSize = 25;
EntityManager entityManager = entityManagerFactory()
.createEntityManager();
EntityTransaction entityTransaction = entityManager
.getTransaction();
try {
entityTransaction.begin();
for (int i = 0; i < entityCount; i++) {
if (i > 0 && i % batchSize == 0) {
entityTransaction.commit();
entityTransaction.begin();
entityManager.clear();
}
Post post = new Post(
String.format("Post %d", i + 1)
);
entityManager.persist(post);
}
entityTransaction.commit();
} catch (RuntimeException e) {
if (entityTransaction.isActive()) {
entityTransaction.rollback();
}
throw e;
} finally {
entityManager.close();
}
此外,请确保使用以下配置属性启用JDBC批处理:
<property
name="hibernate.jdbc.batch_size"
value="25"
/>
<property
name="hibernate.order_inserts"
value="true"
/>
<property
name="hibernate.order_updates"
value="true"
/>
批量处理
批量处理
适用于所有行都符合预定义的过滤条件,因此您可以使用单个UPDATE更改所有记录。
然而,修改数百万条记录的批量更新可能会增加重做日志的大小或在仍使用2PL(两阶段锁定)
的数据库系统上占用大量锁,例如SQL Server。
因此,虽然批量更新是更改多个记录的最有效方法,但您必须注意要更改多少记录以避免长时间运行的事务。
此外,您可以将批量更新与乐观锁定相结合,以使其他OLTP事务不会丢失批量处理过程中所做的更新。