在 Spring-Boot 中设置 Hibernate Fetch/Batch 大小
Setting Hibernate Fetch/Batch size in Spring-Boot
我有一个查询,预计需要 return ~500.000 个元素,这些元素必须进行后处理。这些元素是从 spring-boot 应用程序 JPA/Hibernate 加载的。为了提高操作的整体速度,我使用 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
。因此,除非您将 SELECTMETHOD 更改为 CURSOR(这会大大降低您的查询速度 很多),否则在对 SqlServer 执行时,提取大小的任何更改都不会产生任何影响。
因此,我的问题不在于休眠,而在于底层数据库。
我有一个查询,预计需要 return ~500.000 个元素,这些元素必须进行后处理。这些元素是从 spring-boot 应用程序 JPA/Hibernate 加载的。为了提高操作的整体速度,我使用 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
。因此,除非您将 SELECTMETHOD 更改为 CURSOR(这会大大降低您的查询速度 很多),否则在对 SqlServer 执行时,提取大小的任何更改都不会产生任何影响。
因此,我的问题不在于休眠,而在于底层数据库。