Java Hibernate-SQL很快,但查询速度仍然很慢
我正在运行Hibernate4.1,Javassist运行时工具运行在Hikari池和Oracle12c之上。JDK是1.7 我有一个在数据库上运行非常快的查询,在Hibernate中获取了大约500个实体。根据JProfiler的说法,查询运行时非常小,大约11毫秒,但总的来说Java Hibernate-SQL很快,但查询速度仍然很慢,java,performance,hibernate,Java,Performance,Hibernate,我正在运行Hibernate4.1,Javassist运行时工具运行在Hikari池和Oracle12c之上。JDK是1.7 我有一个在数据库上运行非常快的查询,在Hibernate中获取了大约500个实体。根据JProfiler的说法,查询运行时非常小,大约11毫秒,但总的来说query.list大约运行7秒 我尝试过删除所有过滤器,结果表明大部分时间都花在Javaassist和其他与Hibernate相关的反射调用上(比如AbstractProxyHandler等等)。我读到反射开销应该很小
query.list
大约运行7秒
我尝试过删除所有过滤器,结果表明大部分时间都花在Javaassist和其他与Hibernate相关的反射调用上(比如AbstractProxyHandler
等等)。我读到反射开销应该很小,但似乎不是,而且似乎太多了
您能告诉我这里的瓶颈是什么吗?请确保您正在检索的对象没有子对象是作为选择而不是作为连接而延迟获取的。这可能导致一种称为SELECT N+1的行为,其中Hibernate最终运行一个查询以从各自的表中获取500个对象,然后对每个对象执行一个额外的查询以获取子对象。如果有4个或5个关系作为每条记录的SELECT语句被提取,并且有500条记录,那么为了获取列表,您突然要运行大约2000个查询 我建议打开Hibernate的SQL日志来查看它正在运行哪些查询。如果在获取列表时它转储了一个很长的SELECT查询列表,请查看映射文件以了解如何建立关系。尝试将它们调整为fetch=“join”,看看这些查询是否消失,性能是否有所提高 下面是一些可能相关的堆栈溢出问题,可以提供更具体的细节
关于探查器和其他类似工具,还有一些需要注意的地方。通常在跟踪性能问题时,特定的代码块会显示为花费时间最多的地方。人们通常会得出这样的结论:所讨论的代码块速度很慢。在您的例子中,您似乎正在观察Hibernate的反射代码,因为它是花费时间的地方。很重要的一点是,这个代码本身可能并不是很慢,但它是花费时间的地方,因为它频繁地被调用,这是由于算法复杂性。我发现,在许多问题中,序列化或反射似乎很慢,而实际情况是,代码用于与外部资源通信,并且该资源被调用了1000次,而实际上它应该被调用的次数很少。进行1000次查询以获取列表将导致采样,显示处理这些查询的代码花费了大量时间。小心不要将由于设计/配置问题而经常调用的代码误认为是缓慢的代码。问题很可能不在于hibernate对反射的使用,因为反射通常不会在几秒钟内变慢。确保您正在检索的对象没有作为选择而不是作为连接而缓慢地获取的子对象。这可能导致一种称为SELECT N+1的行为,其中Hibernate最终运行一个查询以从各自的表中获取500个对象,然后对每个对象执行一个额外的查询以获取子对象。如果有4个或5个关系作为每条记录的SELECT语句被提取,并且有500条记录,那么为了获取列表,您突然要运行大约2000个查询 我建议打开Hibernate的SQL日志来查看它正在运行哪些查询。如果在获取列表时它转储了一个很长的SELECT查询列表,请查看映射文件以了解如何建立关系。尝试将它们调整为fetch=“join”,看看这些查询是否消失,性能是否有所提高 下面是一些可能相关的堆栈溢出问题,可以提供更具体的细节
关于探查器和其他类似工具,还有一些需要注意的地方。通常在跟踪性能问题时,特定的代码块会显示为花费时间最多的地方。人们通常会得出这样的结论:所讨论的代码块速度很慢。在您的例子中,您似乎正在观察Hibernate的反射代码,因为它是花费时间的地方。很重要的一点是,这个代码本身可能并不是很慢,但它是花费时间的地方,因为它频繁地被调用,这是由于算法复杂性。我发现,在许多问题中,序列化或反射似乎很慢,而实际情况是,代码用于与外部资源通信,并且该资源被调用了1000次,而实际上它应该被调用的次数很少。进行1000次查询以获取列表将导致采样,显示处理这些查询的代码花费了大量时间。小心不要将由于设计/配置问题而经常调用的代码误认为是缓慢的代码。问题很可能不在于hibernate对反射的使用,因为反射通常不会在几秒钟内变慢。我确实打开了SQL日志记录,而且它只是一个查询,所有相关的集合要么被联合获取,要么不被访问。我的猜测是反射可能并不慢,但由于反射调用的数量,它会扭曲分析器的结果。但我仍然找不到问题的根源,在我的例子中,我甚至把我的实体简化到了最低限度。它基本上是两个常规字段,两个用户类型字段,一个多对一的集合,就是这样。我打开了SQL日志记录,它只是一个查询,所有相关集合要么被联合获取,要么不被访问。我的猜测是,反射可能并不慢,但由于t