首次执行时缓慢的Hibernate查询

时间:2017-11-22 13:42:21

标签: java oracle performance hibernate caching

我有一个(非常)复杂的应用程序,它将GET-Request转换为许多Hibernate查询到Oracle DB。

它基本上检索散布在~100个表中的对象的属性。

即使是边缘情况(=大结果集),我也必须削减最长请求时间。

在边缘情况下,第一次调用时性能极差(即经过一段时间后)。 之后,即使我同时刷新缓冲区缓存和共享池,查询也要快得多。

这适用于SAME GET-Request,即请求的相同对象。请求另一个对象,但在第一次调用时,相同的属性再次花费很长时间。

例如,相同的查询,相同的条件,获取的行总数在(低)千位:

  • 第一次电话:26.000ms
  • 刷新缓冲区缓存/共享池后首次调用:2800ms
  • 冲洗后的第二次通话:1200ms

通过研究网络,我已经发现冲洗池并不一定能真正冲洗它,所以我不能依赖它。

作为一个警告,我是一名开发人员并且具有良好的Oracle工作知识,但我不是DBA,也无法访问完整的DBA。

我怀疑首次执行缓慢的原因如下:

  • Oracle做了很长时间的硬解析(执行的查询可能包含数千个参数):我无法找出“糟糕”的硬解析可能需要多长时间。企业管理器告诉我他只对我的多次执行查询进行了1次硬解析,所以看起来不太可能。

  • 查询本身需要很长时间,但是缓存并且缓存没有被我的操作清空(可能是磁盘缓存?):同样,企业管理器不同意并且总体上显示非常低的查询时间。

  • 我确实首先怀疑Hibernate / Java的原因(毕竟很多对象都要创建),但是性能上的巨大差异似乎不太可能

我对如何进行性能调整感到茫然,并且正在寻找有用的阅读材料和/或关于为什么第一次执行如此缓慢的不同想法。

1 个答案:

答案 0 :(得分:0)

第一个查询通常比Oracle DB中的后续查询花费更多的时间。

在这种情况下单独依赖Oracle缓存似乎不是一个好习惯。但是,如果您可以通过执行虚拟查询(可能是在应用程序启动后立即)来模拟查询,那么这可能会很方便。它可能有助于减少任何后续相等呼叫的执行时间。

虽然这样的解决方案可能有助于提高性能,但是在应用程序级别引入程序化缓存的方式更可靠。它可以用于实体或重复提取的任何其他非持久对象。

请注意,如果问题的范围仅限于数据库,那么它将成为Database Administrators Stack Exchange问题的完美候选者。