简单的休眠查询返回速度非常慢

2022-09-01 15:27:23

我有以下休眠查询:

Query query = session.createQuery("from MyHibernateClass");
List<MyHibernateClass> result = query.list();// executes in 7000ms

当记录在MySQL中执行的sql时,我看到

select 
  myhibernat0_.myFirstColumn as myfirstcolumn92_, 
  myhibernat0_.mySecondColumn as mysecondcolumn92_, 
  myhibernat0_.mythirdcolumn as mythirdcolumn92_, 
  myhibernat0_.myFourthColumn as myfourthcolumn92_ 
from MyHibernateClass myhibernat0_ 
where (1=1);

在 MyHibernateClass 数据库表中 3500 行的小数据集上测量 jvm 中的 java 代码时,大约需要 7000 毫秒。

另一方面,如果我使用直接jdbc,如下所示:

Statement statement = session.connection().createStatement();
ResultSet rs = statement.executeQuery("select * from MyHibernateClass");// 7ms
List<MyHibernateClass> result = convert(rs);// executes in 20ms

我看到相同的sql进入数据库,但现在在jvm中的java代码中花费的时间是7ms。

MyHibernateClass是一个简单的java bean类,带有getters和setters,我没有使用特殊的resulttransformers,如示例中所示。我只需要类的只读实例,并且不需要将其附加到休眠会话。

我宁愿使用休眠版本,但不能接受执行时间。

添加信息:添加休眠日志记录后,我看到

[2011-07-07 14:26:26,643]DEBUG [main] [logid: ] - 
  org.hibernate.jdbc.AbstractBatcher.logOpenResults(AbstractBatcher.java:426) - 
  about to open ResultSet (open ResultSets: 0, globally: 0)

后跟以下 3500 个日志语句

[2011-07-07 14:26:26,649]DEBUG [main] [logid: ] - 
  org.hibernate.loader.Loader.getRow(Loader.java:1197) - 
  result row: EntityKey[com.mycom.MyHibernateClass#1]

后跟 3500 日志语句,如

[2011-07-07 14:27:06,789]DEBUG [main] [logid: ] - 
  org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:130) - 
  resolving associations for [com.mycom.MyHibernateClass#1]
[2011-07-07 14:27:06,792]DEBUG [main] [logid: ] - 
  org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:226) - 
  done materializing entity [com.mycom.MyHibernateClass#1]

这是什么意思?

Hibernate在第一个实现中做了什么,我该如何找到答案?


答案 1

添加具有类所有属性的构造函数可以解决问题,现在休眠查询的执行时间为70ms。以前,该类只有一个不带参数的默认构造函数和一个具有实体 id 参数的构造函数。


答案 2

根据新的信息,我觉得我应该提供另一个答案。这种差异看起来就像您为 Bean 中的 List 或 Set 属性指定了一对多关联。

您可能正在指定将关闭延迟加载的内容。关闭延迟加载后,它将为每个实体获取每个关联的记录,这就是为什么它需要很长时间才能执行的原因。lazy=falseMyHibernateClass

尝试设置,这将执行得更快,然后仅在从实体显式请求关联实体时才检索它们。lazy=true


推荐