在tomcat中的每次循环迭代中,JPA查询变慢

Posted

技术标签:

【中文标题】在tomcat中的每次循环迭代中,JPA查询变慢【英文标题】:JPA query getting slower on each loop iteration in tomcat 【发布时间】:2020-01-12 15:08:28 【问题描述】:

我有一个简单的选择查询,它返回 200 行。该查询被迭代 1437 次。 技术:java 8、spring boot 2.1.3.RELEASE、tomcat、hibernate

在每次迭代中,查询都会变慢。第一个查询需要 55 毫秒,最后一个查询需要 702 毫秒 但是,当我在 Junit "@RunWith(SpringJUnit4ClassRunner.class)" 中启动相同的查询时,查询并没有变慢。每个查询需要 +- 37 毫秒

在Tomcat中运行时的第一个和最后一个日志

运行junit时的第一个和最后一个日志

【问题讨论】:

请提供代码;这将帮助我们帮助您。缺少代码导致大量猜测...... 【参考方案1】:

正如您在日志中看到的,一个区别是实体管理器在 Tomcat 上的每次迭代后都不会关闭(但在 JUnit 上会关闭)。在 1k 次迭代之后,实体管理器将在内存中保存大量对象,并且在这种加载的上下文上的操作变得昂贵。每次迭代的内存压力也应该越来越高。

我会尝试更频繁地clear 上下文(即在每次迭代之后),或者至少增加可用内存以排除 GC 过于频繁地发挥作用。

另见this answer

【讨论】:

【参考方案2】:

我在每次查询后添加了 entitymanager.clear(),这解决了问题。 谢谢级联!!

结果确实令人印象深刻。第一个查询需要 73 毫秒,而对于最后一个查询,它会以相反的方式“下降”到 1 毫秒

【讨论】:

以上是关于在tomcat中的每次循环迭代中,JPA查询变慢的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow迭代速度变慢的问题

如何在循环中的每次迭代中保存具有不同名称的文件? MATLAB

在每次循环迭代中更改记录字段

for 循环是不是在每次迭代中重新评估其主体中的函数?

如何迭代 JPA 查询结果而不将它们全部保留在内存中?

Java 如何为循环中的每次迭代播放声音?