寻找一种使用Spring Data JPA加速数据更新的方法

问题描述 投票:2回答:1

同事们,我很感激以下案例的很多建议。

我们的项目基于Spring Data JPA - 因此我的存储库实现基于SimpleJpaRepository。

要讨论的方法是在标有@Transactional的服务中。 根据我的理解,如果我不插入流程,Spring会创建实体管理器,刷新数据并提交事务。

该项目读取并解析外部json两次。首先运行 - 给json填充表格。第二次运行 - 相同大小的json,这里有一些新值,并提供更新表。

表在用于更新的搜索字段上具有UNIQUE索引。数据对象是基本的,没有@OneToMany关系。

问题:第二次跑步(获得更新)时速度急剧下降。每个新处理的,例如1000条记录的处理速度比前一条慢。因此,update-run比create-run长约10倍

对于create-run,我使用了简单的存储库方法#save,它在#persist和#merge之间选择,仅此而已。显然它在我的案例中选择了#persist。在所有概率中,数据都被刷新,并且事务由Spring提交。我打开了'generate_statistics'选项,按预期创建了1个flush和实数

我是如何尝试加快更新的:

首先,对于更新运行,我将要处理的数据切片成集合(实际上是在每个切片处理结束时清除的集合)并首先调用#saveAll然后调用#flush(实际上是em#flush)这种方法基于在这些讨论How to improve performance of Updating data using JPAHIbernate commit() and flush()

唉,时间花费基本相同,JDBC操作次数相同,刷新次数与预期相同(例如,'pack'大小为1000时刷新29次,'pack'大小为10时刷新2900次)。奇怪的是,这次实体数量与要更新的表中的记录数量不同

日志看起来像

76545093741 nanoseconds spent executing 2860 flushes (flushing a total of 40912292 entities and 0 collections);
756096912142 nanoseconds spent executing 28592 partial-flushes (flushing a total of 408736936 entities and 408736936 collections)

40912292个实体? 408736936实体和集合?但为什么?我也想知道那些部分冲洗是什么 - 它们会引起什么?为什么他们的号码漂浮?

我想知道为什么手动定期冲洗没有帮助。

其次,在之前的尝试中,我使用了数据对象,主键是使用IDENTITY策略自动生成的。

这次我决定尝试批量处理。我将PK生成策略更改为SEQUENCE,并为批处理添加了一堆Spring属性:

jpa:
    properties:
      hibernate:
        jdbc:
          batch_size: 50
          batch_versioned_data: true
          order_inserts: true
          order_updates: true

我在这种情况下收到了什么日志:

250614501 nanoseconds spent preparing 28594 JDBC statements;
8759177291 nanoseconds spent executing 28592 JDBC statements;
3398281 nanoseconds spent executing 2 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
7925542816 nanoseconds spent executing 286 flushes (flushing a total of 4104092 entities and 0 collections);
794086157441 nanoseconds spent executing 28592 partial-flushes (flushing a total of 408736936 entities and 408736936 collections)

所以只有2批......而且速度几乎没有增加

显然smth是错误的,可能是错误的配置。我能以某种方式修复它吗?有没有办法提高更新速度?

  1. 最后......也许是我测试过的最重要的尝试。

在事务完成后创建运行之后,我认为实体已经分离并需要合并(他们在这里说明:Does JPA's commit() method make entity detached?)我甚至重新启动了Jetty。我的更新代码唯一做的就是在更新运行期间设置一个新值。这个新值被神奇地转移到DB而没有调用存储库方法saveAndFlash(即entitymanager.merge):)唉,尽管处理速度没有增加......

hibernate spring-data-jpa entitymanager
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.