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
这是我坚持的方式。其中 valmers 和 pips 是大约 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 对于只有一张表来说太慢了的主要内容,如果未能解决你的问题,请参考以下文章