我的Spring启动应用程序正在使用Hibernate JPA将记录保存到MySQL。
{@ {1}}经过良好而快速的工作后,突然开始非常非常缓慢地工作:插入1K记录(主键是ID)大约需要10分钟。
我虽然问题在于循环调用save()
,所以我改成save()
,但令我惊讶的是没有什么区别,它甚至可能需要20分钟的时间 strong>保存 1139条记录。
MySQL是本地的,仅由我的开发环境使用。
这是日志文件:
saveAll()
我将它们添加到属性文件中:
2018-08-07 14:44:25:335 - About to save all new 1139 cats of Oscar
2018-08-07 15:03:47:758 - Succeded saving the cats of Oscar
2018-08-07 15:07:41:961 - Session Metrics {
600922575 nanoseconds spent acquiring 1140 JDBC connections;
92320112 nanoseconds spent releasing 1139 JDBC connections;
312825484 nanoseconds spent preparing 2283 JDBC statements;
464811479497 nanoseconds spent executing 2279 JDBC statements;
233368433210 nanoseconds spent executing 229 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
233765441110 nanoseconds spent executing 1 flushes (flushing a total of 1139 entities and 0 collections);
40198 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
}
这是Service方法中的代码:
spring.jpa.properties.hibernate.jdbc.batch_size=5
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.generate_statistics=true
答案 0 :(得分:0)
批量大小不会起作用。
这是休眠文档中的重要部分: http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#batch-session-batch-insert
批量插入
当使新对象持久化时,请定期对会话使用flush()和clear()方法,以控制第一级缓存的大小。
示例3.刷新和清除会话
EntityManager entityManager = null;
EntityTransaction txn = null;
try {
entityManager = entityManagerFactory().createEntityManager();
txn = entityManager.getTransaction();
txn.begin();
int batchSize = 25;
for ( int i = 0; i < entityCount; i++ ) {
if ( i > 0 && i % batchSize == 0 ) {
//flush a batch of inserts and release memory
entityManager.flush();
entityManager.clear();
}
Person Person = new Person( String.format( "Person %d", i ) );
entityManager.persist( Person );
}
txn.commit();
} catch (RuntimeException e) {
if ( txn != null && txn.isActive()) txn.rollback();
throw e;
} finally {
if (entityManager != null) {
entityManager.close();
}
}