我有一个查询,预计返回约 500.000 个元素,这些元素必须进行后处理。这些元素是从带有 JPA/Hibernate 的 spring-boot 应用程序加载的。为了提高操作的整体速度,我使用
getResultStream
而不是 getResultList
。
不过,操作速度似乎很低。我尝试了 hibernate fetch-size,它应该适用于这里。
在我的
application.yml
中,获取大小设置为
spring:
jpa:
properties:
hibernate:
jdbc:
batch_size: ...
当我将记录器
org.hibernate.cfg
调试时,我可以看到我设置的值被打印出来。然而,它们似乎没有任何效果。无论提取大小设置为 1、10 还是 2000,执行代码的时间都不会不同。
我在这里做错了什么?
也许您根本没有做错任何事情,只是数据库需要很长时间才能从磁盘获取所有数据并将其发送到您的应用程序。
您可以尝试的一件事是使用
StatelessSession
或尝试在每个例如之后清除持久性上下文。通过 entityManager.clear()
获得 20 个元素。也许速度减慢是由于持久性上下文填满了所有这些元素并导致内存压力。
如果没有任何进一步的信息,我们无法为您提供帮助。
在实体中,使用分配的生成器,因为 MySQL IDENTITY 将导致插入批处理被禁用。如果您有自动递增 id,则批处理将不起作用。我使用@Id并提供了UUID,批量工作。
所以,我们刚刚经历了惨痛的教训,SqlServer 忽略了默认 SELECTMETHOD=DIRECT 中的获取大小,并且总是按原样传输整个
ResultSet
。因此,在针对 SqlServer 执行时,获取大小的任何更改都不会产生任何影响,除非您将 SELECTMETHOD 更改为 CURSOR(这会减慢查询速度很多)。
因此,我的问题不在于休眠,而在于底层数据库。