简单的hibernate查询返回非常缓慢
我有以下的hibernate查询:
Query query = session.createQuery("from MyHibernateClass"); List<MyHibernateClass> result = query.list();// executes in 7000ms
logging在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代码时,大约需要7000ms。
如果我另一方面使用直接jdbc,如下所示:
Statement statement = session.connection().createStatement(); ResultSet rs = statement.executeQuery("select * from MyHibernateClass");// 7ms List<MyHibernateClass> result = convert(rs);// executes in 20ms
我看到相同的数据库进入数据库,但现在花费在jvm中的java代码的时间是7ms。
MyHibernateClass是一个简单的带有getter和setter的java bean类,我没有使用特殊的resulttransformers,如示例中所示。 我只需要一个类的只读实例,它不需要连接到hibernate会话。
我宁愿使用hibernate版本,但不能接受执行时间。
添加的信息 :添加hibernate日志后,我看到
[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在第一次执行时做了什么,我怎么知道?
添加一个具有类的所有属性的构造函数的窍门,现在的执行时间为70毫秒hibernate查询。 以前这个类只有一个没有参数的默认构造函数和一个带有实体id参数的构造函数。
基于新的信息,我觉得我应该提供另一个答案。 差异看起来像是在bean中为List或Set属性指定了一对多关联。
您可能指定了lazy=false
,这将closures延迟加载。 closures延迟加载它将获取每个MyHibernateClass
实体的每个关联logging,这就是为什么它需要这么长的时间来执行。
尝试设置lazy=true
,这将执行得更快,然后只从实体明确请求时才检索关联的实体。
如果在应用程序中使用Log4j,则可以设置Hibernate特有的各种不同的日志logging选项,以便更好地了解Hibernate中幕后的情况。
我的猜测是,这是在应用程序中首次调用HQL查询时发生的典型初始加载时间。 在第一次之后,后续的HQL查询应该明显快得多。
我知道这个线程是旧的,但更新我遇到了同样的问题,但与SQL Server,事实certificate,由Hibernate和SQL使用驱动程序发送的SQL是不同的。 默认情况下使用MSSQL驱动程序将查询作为RPC调用的存储过程发送,这是因为驱动程序试图优化MSSQL Standards的查询计划,所以它发送查询
hibernate查询:
select c.col1,c.col2 from customer c where c.name like @param1 and c.country like @param2
实际的驱动程序发送查询:
@param1=somevalue, @param2=somevalue declar sp .... select c.col1,c.col2 from customer c where c.name like @param1 and c.country like @param2 go
注意:这个查询我通过SQL Profiler工具直接在数据库上侦听
事实certificate,MSSQL上的sp_exec优化倾向于产生被caching的好的查询计划,但是这会导致“参数嗅探”来更多地了解这个问题。
所以为了克服这个,我有以下select:
-
将我的HQL更改为本地查询并为某些参数添加选项重新指定
-
使用直接查询值而不是准备好的语句,所以参数值将不会被翻译,查询也不会被驱动程序修改为存储过程
-
更改驱动程序设置为不发送存储过程(这仍然是坏的,因为现在MSSQL服务器中的查询计划将特定于此查询,这与Option:2相同,但在代码之外)
我不想使用OPTION 1和2,因为这消除了使用ORM框架的全部目的,现在我终于使用OPTION 3
所以我改变了JDBC URL来发送选项prepareStatement = false
设置后,我有一个问题的查询被发送像
Select * from customer c where c.name like **N**'somename' and c.country=**N**'somevalue'
这里有一个前缀的值,表示要转换的编码scheme,所以我禁用JDBC url sendUnicode = false
这一切我在JTDS驱动程序的选项..就我而言,现在的应用程序运行快速。 我还引入了二级caching来caching一段时间。
希望这有助于某人,如果你有任何好的build议,请让我知道。
我知道这是一个古老的问题,但这里是固定的我…
在你的hibernate.cfg.xml中,确保你有正确的!DOCTYPE …应该如下:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
我有一个事件,我的应用程序总是使用查询的结果集中的每一行。 通过使用下面的setFetchSize方法设置我的读取大小,我发现速度提高了40倍。 (性能改进包括添加计数查询。)
Long count = getStoreCount(customerId); Query query = session.getNamedQuery("hqlGetStoresByCustomerId") .setString("i_customerid",customerId) .setFetchSize(count.intValue());
这样做时要小心; 我的数据集有大约100行,它的范围是一个Web请求的生命周期。 如果你有更大的数据集,那么在返回到Java Heap之前,你将在这个数据的存在期间吃掉Java Heap。
在我发现DOCTYPE标签写在hibernate.cfg.xml
和*mapping object*.hbm.class
之前,我花了10秒钟来执行一个简单的select所有查询
确保hibernate.cfg.xml
以
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
和映射xml.class
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
现在花了我1-2秒来执行任何查询。
- 为什么复合键在hibernate时不鼓励?
- 如何使用JPA和Hibernate解决LazyInitializationException
- hibernate错误:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已经与会话关联
- JPA / Hibernate原生查询不识别参数
- 使用Hibernate注释的文本字段
- 在JUnit中使用Springtesting服务时如何回滚数据库事务?
- 冬眠4和约达时间
- Hibernate延迟加载应用程序devise
- PersistenceContext EntityManager注入NullPointerException