繁体   English   中英

Hibernate-SQL很快,但是查询仍然很慢

[英]Hibernate - SQL is fast, but query is still slow

我正在使用Javassist运行时工具在Oracle 12c之上的Hikari池上运行Hibernate 4.1。 JDK是1.7。

我有一个查询,该查询在数据库上运行非常快,并在Hibernate中获取约500个实体。 根据JProfiler,查询运行时很小,大约11毫秒,但Query.list总共运行大约7秒钟。

我尝试删除所有过滤器,结果表明大部分时间都花在Javaassist和其他与Hibernate相关的反射调用(如AbstractProxyHandler等)上。 我读到反射开销应该很小,但似乎不是,似乎太多。

您能告诉我这里的瓶颈是什么吗?

确保您要检索的对象没有作为SELECT而不是作为JOIN急切地延迟获取的子对象。 这可能导致称为SELECT N + 1的行为,在该行为中,Hibernate最后运行查询以从其各自的表中获取500个对象,然后对每个对象进行附加查询以获取子对象。 如果有4个或5个关系作为每个记录的SELECT语句获取,并且有500条记录,则突然要运行2000个查询才能获取列表。

我建议为Hibernate打开SQL日志记录,以查看它正在运行哪些查询。 如果在获取列表时转储了很长的SELECT查询列表,请查看映射文件以了解如何建立关系。 尝试将它们调整为fetch =“ join”,看看这些查询是否消失了,性能是否得到了改善。

以下是一些可能相关的堆栈溢出问题,这些问题可能能够提供更具体的细节。

休眠FetchMode SELECT vs JOIN

什么是N + 1 SELECT查询问题?

关于探查器和其他此类工具的其他注意事项。 通常,在跟踪性能问题时,特定的代码块将显示为花费最多的时间。 人们倾向于跳转到一个普遍的结论,即所讨论的代码块很慢。 在您的情况下,您似乎正在观察Hibernate的反射代码,因为它是花费时间的地方。 非常重要的一点是,考虑到此代码本身实际上可能不会很慢,但是由于算法复杂性 而经常调用它,因此它是花费时间的地方。 我发现许多问题,当现实是使用代码与外部资源进行通信时,序列化或反射似乎很慢,并且该资源被调用了数千次,而只能被称为少数。 进行数千次查询以获取您的列表将导致您的采样显示,在处理这些查询的代码中花费了大量时间。 注意不要将由于设计/配置问题而经常调用的代码误认为是缓慢的代码。 问题很可能不在于休眠对反射的使用,因为反射通常不会在几秒钟的时间内变慢。

暂无
暂无

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

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