为什么Hibernate query.list()会变慢?

use*_*479 15 java hibernate

我正在使用Hibernate 4.1.6并且存在构建列表的速度问题.我正在运行以下查询.

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));
}
Run Code Online (Sandbox Code Playgroud)

我设置了hibernate调试以获取发送到数据库的实际查询.我直接在数据库中运行了该查询,并在0.015毫秒内返回了23,000行.所以,我猜测查询不是问题.上面的示例显示创建该列表需要大约32秒.有什么办法可以加快速度吗?

更新:我尝试使用hibernate调试查询使用createSQLQuery()方法,它的运行速度与createQuery()方法一样慢.

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

更新:我输出了一些统计信息(将hibernate.generate_statistics标志设置为true)但没有任何看起来令我担心:

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]
]
Run Code Online (Sandbox Code Playgroud)

更新:从本机查询的ScrollableResults执行next()时,我看到同样的缓慢.请注意,我在循环中什么都不做.

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

Phi*_*enn 7

我对这个答案并不是100%肯定,因为调整/优化问题总是难以确定.

但是,根据您打开的事实show_sql,提取查询,并直接对数据库运行它,并通过Hibernate Query查看亚秒结果与执行时间,我关注的是Hibernate构建和保护对象的方式query.list()通话结果.

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

听起来他们偶然发现了这个修复,并且没有清楚地理解为什么这个有效.有人猜测Hibernate必须使用反射来检测属性.我很好奇自己,并且正计划深入挖掘Hibernate的源代码,以便在有机会时更好地理解这一点.与此同时,您可能希望考虑添加这些完整的构造函数以及所有POJO类属性的参数,并查看这是否有所不同.

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