Spring Data Save vs SaveAll性能 [英] Spring data save vs saveAll performance
问题描述
我试图理解为什么saveAll具有比Spring Data存储库中的保存更好的性能.我正在使用CrudRepository
,可以在此处.
I'm trying to understand why saveAll has better performance than save in the Spring Data repositories. I'm using CrudRepository
which can be seen here.
为了进行测试,我创建了10k个实体并将其添加到列表中,这些实体只有一个id和一个随机字符串(对于基准测试,我将该字符串保持恒定).遍历我的列表并在每个元素上调用.save
,花了40秒.在2秒内完成的同一整个列表上调用.saveAll
.甚至用30k元素调用.saveAll
都花了4秒钟.我确保在执行每个测试之前截断我的表.即使将.saveAll
调用分批处理到50个子列表,也要花费10秒和30k的时间.
To test I created and added 10k entities, which just have an id and a random string (for the benchmark I kept the string a constant), to a list. Iterating over my list and calling .save
on each element, it took 40 seconds. Calling .saveAll
on the same entire list completed in 2 seconds. Calling .saveAll
with even 30k elements took 4 seconds. I made sure to truncate my table before performing each test. Even batching the .saveAll
calls to sublists of 50 took 10 seconds with 30k.
带有整个列表的简单.saveAll
似乎是最快的.
The simple .saveAll
with the entire list seems to be the fastest.
I tried to browse the Spring Data source code but this is the only thing I found of value. Here it seems .saveAll
simply iterates over the entire Iterable
and calls .save
on each one like I was doing. So how is it that much faster? Is it doing some transactional batching internally?
推荐答案
如果没有您的代码,我想,我认为这与在saveAll
的情况下进行一笔交易相对应.
Without having your code, I have to guess, I believe it has to do with the overhead of creating new transaction for each object saved in the case of save
versus opening one transaction in the case of saveAll
.
请注意,save
和saveAll
的定义均用@Transactional
注释.如果您的项目配置正确(由于将实体保存到数据库,这似乎是事实),则意味着只要调用这些方法之一就将创建事务.如果您正在循环中调用save
,这意味着每次调用save
都会创建一个新的事务,但是对于saveAll
而言,只有一个调用,因此无论所涉及的实体数量是多少,都会创建一个事务已保存.
Notice the definition of save
and saveAll
they are both annotated with @Transactional
. If your project is configured properly, which seems to be the case since entities are being saved to the database, that means a transaction will be created whenever one of these methods are called. if you are calling save
in a loop that means a new transaction is being created each time you call save
, but in the case of saveAll
there is one call and therefor one transaction created regardless of the number of entities being saved.
我假设测试本身不是在事务内运行,如果要在事务内运行,则所有保存调用都将在该事务内运行,因为默认事务传播为Propagation.REQUIRED
,意味着如果已经打开了一个事务,则将在其中运行调用.如果您打算使用spring数据,强烈建议您阅读春季的交易管理.
I'm assuming that the test is not itself being run within a transaction, if it were to be run within a transaction then all calls to save will run within that transaction since the the default transaction propagation is Propagation.REQUIRED
, that means if there is a transaction already open the calls will be run within it. If your planning to use spring data I strongly recommend that you read about transaction management in Spring.
这篇关于Spring Data Save vs SaveAll性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!