简体   繁体   English

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

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

I'm running Hibernate 4.1 with Javassist runtime instrumentation running on top of Hikari pool, on top of Oracle 12c. 我正在使用Javassist运行时工具在Oracle 12c之上的Hikari池上运行Hibernate 4.1。 JDK is 1.7. JDK是1.7。

I have a query that runs pretty fast on the database and fetches about 500 entities in Hibernate. 我有一个查询,该查询在数据库上运行非常快,并在Hibernate中获取约500个实体。 The query runtime, according to JProfiler is quite small, about 11 ms, but in total Query.list runs about 7 seconds. 根据JProfiler,查询运行时很小,大约11毫秒,但Query.list总共运行大约7秒钟。

I've tried removing all filters and it shows that most of the time is spent in Javaassist and other Hibernate-related reflection calls (like AbstractProxyHandler and such). 我尝试删除所有过滤器,结果表明大部分时间都花在Javaassist和其他与Hibernate相关的反射调用(如AbstractProxyHandler等)上。 I read that the reflection overhead should be pretty small, but it seems like it is not, and it seems like it is too much. 我读到反射开销应该很小,但似乎不是,似乎太多。

Could you please advise what could be the bottleneck here? 您能告诉我这里的瓶颈是什么吗?

Make sure the object you are retrieving does not have sub-objects that are being fetched lazily as a SELECT instead of eagerly as a JOIN. 确保您要检索的对象没有作为SELECT而不是作为JOIN急切地延迟获取的子对象。 This can result in a behavior known as SELECT N + 1, where Hibernate ends up running a query to get the 500 objects from their respective table, then an additional query for each object to get the child object. 这可能导致称为SELECT N + 1的行为,在该行为中,Hibernate最后运行查询以从其各自的表中获取500个对象,然后对每个对象进行附加查询以获取子对象。 If you have 4 or 5 relationships that are being fetched as SELECT statements for each record, and you have 500 records, suddenly you're running around 2000 queries in order to get the List. 如果有4个或5个关系作为每个记录的SELECT语句获取,并且有500条记录,则突然要运行2000个查询才能获取列表。

I would recommend turning on the SQL logging for Hibernate to see which queries it's running. 我建议为Hibernate打开SQL日志记录,以查看它正在运行哪些查询。 If it dumps out a really long list of SELECT queries when you're fetching your list, look at your mapping file to see how your relationships are set up. 如果在获取列表时转储了很长的SELECT查询列表,请查看映射文件以了解如何建立关系。 Try adjusting them to be a fetch="join" and see if those queries go away and if the performance improves. 尝试将它们调整为fetch =“ join”,看看这些查询是否消失了,性能是否得到了改善。

Here are some possibly related Stack Overflow questions that may be able to provide more specific details. 以下是一些可能相关的堆栈溢出问题,这些问题可能能够提供更具体的细节。

Hibernate FetchMode SELECT vs JOIN 休眠FetchMode SELECT vs JOIN

What is N+1 SELECT query issue? 什么是N + 1 SELECT查询问题?

Something else to note about profilers and other tools of that nature. 关于探查器和其他此类工具的其他注意事项。 Often when tracking down a performance issue, a particular block of code will show up as where the most time is being spent. 通常,在跟踪性能问题时,特定的代码块将显示为花费最多的时间。 The common conclusion people tend to jump to is that the block of code in question is slow. 人们倾向于跳转到一个普遍的结论,即所讨论的代码块很慢。 In your case, you seem to be observing Hibernate's reflective code as being where the time is spent. 在您的情况下,您似乎正在观察Hibernate的反射代码,因为它是花费时间的地方。 It is very important to consider that this code itself might not actually be slow, but it is where the time is being spent because it is being called frequently due to algorithm complexity . 非常重要的一点是,考虑到此代码本身实际上可能不会很慢,但是由于算法复杂性 而经常调用它,因此它是花费时间的地方。 I have found in many problems, serialization or reflection appears to be slow, when the reality is that the code is used to communicate with an external resource, and that resource is being called 1000s of times when it should only be called a handful. 我发现许多问题,当现实是使用代码与外部资源进行通信时,序列化或反射似乎很慢,并且该资源被调用了数千次,而只能被称为少数。 Making 1000s of queries to fetch your list will result in your sampling showing that a lot of time is being spent in the code that processes those queries. 进行数千次查询以获取您的列表将导致您的采样显示,在处理这些查询的代码中花费了大量时间。 Be careful not to mistake code that is called often due to a design/configuration issue for code that is slow. 注意不要将由于设计/配置问题而经常调用的代码误认为是缓慢的代码。 The problem very likely does not lay in hibernate's use of reflection, since reflection generally isn't slow on the order of seconds. 问题很可能不在于休眠对反射的使用,因为反射通常不会在几秒钟的时间内变慢。

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

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