为啥在单个记录上调用 Spring Data JPA save() 而不是在记录列表上调用它时速度很慢?
Posted
技术标签:
【中文标题】为啥在单个记录上调用 Spring Data JPA save() 而不是在记录列表上调用它时速度很慢?【英文标题】:Why Spring Data JPA's save() is slow when called on a single record vs calling it on a list of records?为什么在单个记录上调用 Spring Data JPA save() 而不是在记录列表上调用它时速度很慢? 【发布时间】:2018-05-08 07:51:00 【问题描述】:在single record vs calling save on a list of records
上使用SimpleJpaRepository
中的save
函数时,我的时间大大减少。
下面的循环花费10
比list
长。
for (Record r : csvRecords)
myRepository.save(r);
myRepository
根本没有任何 @Transactional
注释。
但是与上面的相比,下面的循环速度非常快。
List<Record> myArray = new ArrayList();
for (Record r : csvRecords)
myArray.add(r);
myRepository.save(myArray);
如果我们查看SimpleJpaRepository
中的save
实现
@Transactional
public <S extends T> List<S> save(Iterable<S> entities)
List<S> result = new ArrayList<S>();
if (entities == null)
return result;
for (S entity : entities)
result.add(save(entity));
return result;
这个实现只是屏蔽了单个 save
操作,所以如果我首先将数据存储在缓冲区中或者我在每条记录上调用 save 应该没有任何区别,因此速度增加对于我。
编辑: 使用docs.spring.io/autorepo/docs/spring-data-commons/1.5.1.RELEASE/ 版本。
【问题讨论】:
你确定你没有使用SimpleJpaRepository
的子类,它用更优化的东西覆盖save(Iterable)
方法吗?
如果对 save()
进行 10 次单次调用,您将执行 10 次事务,但如果使用 10 条记录列表调用 save()
,则只有一次。这可能是您观察的原因。
JPA API 没有这样的“保存”方法。也许您的意思是“Spring Data JPA”,它不是 JPA API。
@DN1 感谢您的评论。
【参考方案1】:
在单个条目的情况下,您打开 10 笔交易 - 需要打开和关闭;在List
的情况下,save(singleEntry)
(在saveAll
内部使用)将重新使用已经打开的事务,因此它是一个打开和关闭的单一事务。顺便说一句,如果我正确地重新调用它的saveAll(Iterable)
not save(Iterable)
。
【讨论】:
感谢您指出! docs.spring.io/autorepo/docs/spring-data-commons/1.5.1.RELEASE/… 显然我使用的是旧版本。 @Oleg 啊!这是有道理的。以上是关于为啥在单个记录上调用 Spring Data JPA save() 而不是在记录列表上调用它时速度很慢?的主要内容,如果未能解决你的问题,请参考以下文章
spring-data-jpa循环保存数据,为啥只保存了最后一条数据
为啥我不能在 super 上调用 Core Data Accessors?