首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Hibernate - SQL是快速的,但是查询仍然很慢。

Hibernate - SQL是快速的,但是查询仍然很慢。
EN

Stack Overflow用户
提问于 2017-09-25 17:15:04
回答 1查看 1.9K关注 0票数 2

我正在运行Hibernate 4.1,在Hikari池之上,在Oracle 12c上运行Javassist运行时工具。JDK为1.7。

我有一个查询,它在数据库上运行得相当快,并在Hibernate中获取大约500个实体。根据JProfiler的说法,查询运行时非常小,约为11 ms,但Query.list总共运行约7秒。

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

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

EN

回答 1

Stack Overflow用户

发布于 2017-09-25 17:38:56

确保您要检索的对象没有子对象,这些子对象作为SELECT而不是JOIN被延迟地获取。这可能导致名为SELECT N+ 1的行为,其中Hibernate运行一个查询从各自的表中获取500个对象,然后对每个对象进行额外的查询以获取子对象。如果您有4或5个关系被作为每个记录的SELECT语句获取,并且您有500条记录,那么突然之间,您正在运行大约2000条查询以获得列表。

我建议打开Hibernate的SQL日志,看看它正在运行哪些查询。如果在获取列表时,它转储出一个非常长的SELECT查询列表,请查看映射文件以查看如何设置关系。尝试将它们调整为一个fetch=“联接”,看看这些查询是否消失,以及性能是否有所提高。

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

Hibernate FetchMode SELECT vs JOIN

What is N+1 SELECT query issue?

还有一些关于分析器和其他类似工具的需要注意的地方。通常,在跟踪性能问题时,某个特定的代码块会显示为花费最多时间的地方。人们通常倾向于跳过的结论是,所讨论的代码块是缓慢的。在您的例子中,您似乎是在观察Hibernate的反射代码,因为它是花费时间的地方。非常重要的是要考虑到这段代码本身可能并不是很慢,但是由于算法的复杂性,这是花费时间的地方,因为它经常被调用。我发现,在许多问题中,序列化或反射似乎很慢,而实际情况是,代码用于与外部资源通信,而该资源被调用1000 s,而它只应该被称为少数几个。进行1000 s的查询来获取您的列表将导致您的抽样结果,表明在处理这些查询的代码中花费了大量时间。注意,不要将经常由于设计/配置问题而被调用的代码误认为是缓慢的代码。问题很可能不在于hibernate对反射的使用,因为反射通常不会按秒的顺序缓慢。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46410689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档