简体   繁体   English

在 Spring-Boot 中设置 Hibernate Fetch/Batch 大小

[英]Setting Hibernate Fetch/Batch size in Spring-Boot

I have a query, which is expected to return ~500.000 elements, which have to be postprocessed.我有一个查询,预计将返回 ~500.000 个元素,这些元素必须进行后处理。 The elements are loaded from a spring-boot app with JPA/Hibernate.这些元素是从带有 JPA/Hibernate 的 spring-boot 应用程序加载的。 To increase the overall speed of the operation I use the getResultStream instead of getResultList .为了提高操作的整体速度,我使用getResultStream而不是getResultList

Still, the speed of the operation seems to low.不过,操作的速度似乎很低。 I experimented with the hibernate fetch-size, which should be applicable here.我试验了 hibernate fetch-size,它应该适用于这里。

In my application.yml the fetch size is set in在我的application.yml ,提取大小设置为

spring:
  jpa:
    properties:
      hibernate:
        jdbc:
          batch_size: ...

When I put the logger org.hibernate.cfg to debug, I can see that the values I set are printed out.当我将记录器org.hibernate.cfg进行调试时,我可以看到我设置的值被打印出来了。 However, they seem to have no effect whatsoever.然而,它们似乎没有任何效果。 Whether the fetch size is set to 1, 10 or 2000 the time for executing the code never differs.无论提取大小设置为 1、10 还是 2000,执行代码的时间永远不会不同。

What am I doing wrong here?我在这里做错了什么?

Maybe you are simply not doing anything wrong and it just takes the database that long to fetch all the data from disk and send it to your application.也许您只是没有做错任何事情,只是需要数据库很长时间才能从磁盘获取所有数据并将其发送到您的应用程序。

One thing you can try is to use a StatelessSession or try to clear the persistence context after every eg 20 elements by doing entityManager.clear() .您可以尝试的一件事是使用StatelessSession或尝试通过执行entityManager.clear()在每 20 个元素之后清除持久性上下文。 Maybe the slowdown is due to the persistence context filling up with all those elements and causing memory pressure.也许放缓是由于持久性上下文充满了所有这些元素并导致内存压力。

Without any further information, it's impossible to help you though.如果没有任何进一步的信息,就不可能帮助你。

In the entity, use the assigned generator since MySQL IDENTITY will cause insert batching to be disabled.在实体中,使用指定的生成器,因为 MySQL IDENTITY 会导致插入批处理被禁用。 If you have auto increment id, batch will not work.如果您有自动增量 ID,批处理将不起作用。 I used @Id and provided UUID, batch worked.我使用了@Id 并提供了 UUID,批处理工作。

So, we just learned the hard way, that SqlServer ignores the fetch size in the default SELECTMETHOD=DIRECT and simply always transfers the whole ResultSet as is.所以,我们刚刚学到了困难的方法,SqlServer 忽略默认 SELECTMETHOD=DIRECT 中的获取大小,并且总是按原样传输整个ResultSet Therefore, any changes in the fetch size will have no effect when executed against SqlServer unless you change the SELECTMETHOD to CURSOR (which will slow your queries down a lot ).因此,当对SqlServer的,除非你改变SELECTMETHOD到CURSOR(这会减慢你的查询了很多)来执行的获取大小的任何更改将没有任何效果。

My issue was therefore not with hibernate but with the underlying database.因此,我的问题不在于休眠,而在于底层数据库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM