saveAll 对于只有一张表来说太慢了

Posted

技术标签:

【中文标题】saveAll 对于只有一张表来说太慢了【英文标题】:saveAll is too slow for only one table 【发布时间】:2020-10-03 13:22:09 【问题描述】:

我在MSSQL 有两张桌子。本质上两者是相同的。但是对于其中之一,当我尝试坚持使用saveAll() 时,这需要很多时间。

我的实体是:

@Data
@Entity
@Table(name = "INSTRUMENTOS_PIP")
@IdClass(value = InstrumentosPIPPk.class)
public class InstrumentosPIP

@Data
@Entity
@Table(name = "INSTRUMENTOS_VALMER")
@IdClass(value = InstrumentosValmerPk.class)
public class InstrumentosValmer

我的属性:

spring.jpa.properties.hibernate.jdbc.batch_size=20
spring.jpa.properties.hibernate.order_inserts=true

这是我坚持的方式。其中 valmerspips 是大约 25,000 行的列表

vValmer.saveAll(valmers);
            valmers.clear();
            valmers = null;
            System.gc();

vPIP.saveAll(pips);
            pips.clear();
            pips = null;
            System.gc();

valmers 非常快,但 pips 不是。 valmers 花费 5 分钟,点 2 小时。处理顺序无关紧要。

我正在使用JPARepository

【问题讨论】:

您的 MSSQL 服务器接受这么多并行请求的能力如何? 【参考方案1】:

您是否尝试过分析您的代码?此外,您可以识别的两个表之间是否有任何差异(例如不同的索引)?

一般来说,JPA 不是批处理操作的理想选择,因为它会引入显着的性能开销。最好使用普通的 JDBC。您可能还会发现 Spring Batch 很方便,特别是如果需要另一个步骤将数据映射到实体(例如从文件中)。

附带说明,您似乎认为valmers.clear(); valmers = null; System.gc(); 释放了占用的内存,但请记住,如果代码本身包装在事务中,那么实体将保留在持久性上下文中。在内存方面,实际上证明将输入分成更小的批次并在保存每个批次后执行JpaRepository.flush() 后跟EntityManager.clear() 更有效。

【讨论】:

以上是关于saveAll 对于只有一张表来说太慢了的主要内容,如果未能解决你的问题,请参考以下文章

PHP CURL 对于本地主机来说太慢了

PHP CURL 对于本地主机来说太慢了

VS Code - 重命名符号对于 Python 来说太慢了

postgresql全文搜索查询太慢

Mongodb查询对索引字段的部分字段搜索来说太慢了

安卓颜色飞溅