为什么Hibernate的query.list()很慢? [英] Why is the Hibernate query.list() slow?

查看:549
本文介绍了为什么Hibernate的query.list()很慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Hibernate 4.1.6,并且遇到了构建列表的速度问题。我正在运行以下查询。

  public void doQuery(final Baz baz){
final Query query = getSessionFactory( ).getCurrentSession()。createQuery(
从foo中选择c.id,foo.someValue作为foo+
加入foo.a作为+
加入foo.b as b+
加入bc为c+
其中baz =:baz
);
query.setParameter(baz,baz);
长启动= System.currentTimeMillis();
final List< Object []> list = query.list();
Long end = System.currentTimeMillis();
System.out.println((end-start));

我将hibernate调试设置为获取发送到数据库的实际查询。我直接在数据库中运行该查询,并在0.015 ms内返回了23,000行。所以,我猜猜查询不是问题。上面的例子显示它需要约32秒来创建该列表。有什么可以加快速度吗?更新:我尝试使用hibernate调试查询的createSQLQuery()方法,它的运行速度与createQuery()方法。



更新:我尝试使用无状态会话,但运行速度很慢。



更新:我输出了一些统计信息(将hibernate.generate_statistics标志设置为true),但是没有什么让我感到惊讶:

  Hibernate SessionFactory统计信息[
连接请求的数量[4]
在会话上完成的刷新次数(通过客户端代码或hibernate [3]
完成的事务数(失败和成功)。[ 3]
无故障完成的交易数[3]
您的代码已打开的会话数[4]
您的代码已关闭的会话数[3]
执行的查询总数[4]
执行最慢查询的时间[28258]
the [6]
从DB加载的集合数量[6]
重建的集合数量[0]
从数据库中提取的集合数量
已更新批次的集合数量[0]
已删除对象的数量[0]
获取的对象数量。 [1]
实际加载的对象数量(完全填充)[204]
插入的对象数量[1]
更新对象的数量[0]
]

Hibernate SessionFactory查询统计[
此查询[0]
在缓存上的总点击数]
此查询的缓存总数未命中[0]
此查询执行时放入缓存的对象总数[0]
此查询被调用的次数[1]
调用此查询的平均时间[28258]
最大时间通过查询执行[28258]
查询引起的最短时间e执行[28258]
通过此查询的所有调用返回的行数[23303]
]

更新:从本机查询的ScrollableResults执行next()时,看到相同的缓慢。请注意,我在循环中没有做任何事情。

  ScrollableResults results = query.scroll(); 
长启动= System.currentTimeMillis();
while(results.next()){
// do nothing
}
Long end = System.currentTimeMillis();
System.out.println((end-start));


解决方案

调谐/优化问题总是很难查明。然而,基于你打开 show_sql 的事实,提取​​了查询,并直接运行它数据库,并通过Hibernate查询看到亚秒级的结果与执行时间,我将重点放在Hibernate构建和保护由 query.list()产生的对象的方式上。 call。

这是另外一位在Hibernate中提到类似查询性能问题的用户,通过添加完整的便利构造函数(构造函数接受每个字段的值)在POJO中:简单的hibernate查询返回非常缓慢



这听起来像是他们偶然发现了这个问题,并且没有清楚地理解这个原因。有人猜测Hibernate必须使用反射来检测属性。我很好奇自己,并计划深入研究Hibernate的源代码,以便在有机会时更好地理解这一点。同时,你可能希望考虑添加这些完整的构造函数,并为它们添加所有POJO类属性的参数,并查看是否有所作为。

请让我知道您发现了什么,因为我对Hibernate性能优化非常感兴趣。谢谢!


I am using Hibernate 4.1.6 and having issues with the speed that a list is built. I am running the following query.

public void doQuery(final Baz baz){
  final Query query = getSessionFactory().getCurrentSession().createQuery(
          "select c.id, foo.someValue from Foo as foo "+
          "join foo.a as a"+
          "join foo.b as b "+
          "join b.c as c "+
          "where baz=:baz"
          );
  query.setParameter("baz", baz);
  Long start=System.currentTimeMillis();
  final List<Object[]> list = query.list();
  Long end=System.currentTimeMillis();
  System.out.println((end-start));
}

I set hibernate debugging on to get the actual query that is sent to the database. I ran that query directly in the database and it returned 23,000 rows in 0.015 ms. So, I'm guessing the query is not the issue. The example above shows it takes ~ 32 seconds to create that list. Is there something that can be done to speed that up?

Update: I tried using the createSQLQuery() method using the hibernate debugging query and it ran just as slow as the createQuery() method.

Update: I tried using a stateless session but it ran just as slow.

Update: I outputted some statistics (setting the hibernate.generate_statistics flag to true) but nothing looks alarming to me:

Hibernate SessionFactory Statistics [
    Number of connection requests[4]
    Number of flushes done on the session (either by client code or by hibernate[3]
    The number of completed transactions (failed and successful).[3]
    The number of transactions completed without failure[3]
    The number of sessions your code has opened.[4]
    The number of sessions your code has closed.[3]
    Total number of queries executed.[4]
    Time of the slowest query executed.[28258]
    the number of collections fetched from the DB.[6]
    The number of collections loaded from the DB.[6]
    The number of collections that were rebuilt[0]
    The number of collections that were 'deleted' batch.[0]
    The number of collections that were updated batch.[0]
    The number of your objects deleted.[0]
    The number of your objects fetched.[1]
    The number of your objects actually loaded (fully populated).[204]
    The number of your objects inserted.[1]
    The number of your object updated.[0]
]

Hibernate SessionFactory Query Statistics [
    total hits on cache by this query[0]
    total misses on cache by this query[0]
    total number of objects put into cache by this query execution[0]
    Number of times this query has been invoked[1]
    average time for invoking this query.[28258]
    maximum time incurred by query execution[28258]
    minimum time incurred by query execution[28258]
    Number of rows returned over all invocations of this query[23303]
]

Update: I see the same slowness when doing a next() from a ScrollableResults from a native query. Note that I am doing nothing in the loop.

    ScrollableResults results = query.scroll();
    Long start=System.currentTimeMillis();
    while (results.next()) {
       //do nothing
    }
    Long end=System.currentTimeMillis();
    System.out.println((end-start));

解决方案

I am not 100% certain on this answer, since tuning / optimization issues are always so difficult to pinpoint.

However, based on the fact that you turned on show_sql, extracted the query, and ran it directly against the database and saw sub-second results vs execution time through Hibernate Query, I am focusing on the manner in which Hibernate is constructing and hydrating objects that result from the query.list() call.

Here is another user who mentioned similar Query performance issues in Hibernate, and saw dramatic performance increases by adding full convenience constructors (constructors that accept a value for each field) in the POJO: Simple hibernate query returning very slowly

It sounds like they stumbled upon this fix, and there was not a clear understanding of why this worked. There was speculation regarding Hibernate having to use reflection to detect properties. I am curious myself and am planning to dig into the source code for Hibernate to better understand this when I have a chance. In the meantime, though, you may wish to look into adding these full constructors with parameters for all of your POJO class attributes and see if that makes a difference.

Please do let me know what you find, as I am very interested in Hibernate performance optimization. Thanks!

这篇关于为什么Hibernate的query.list()很慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆