首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Hibernate HQL createQuery

Hibernate HQL createQuery
EN

Stack Overflow用户
提问于 2012-04-10 05:27:34
回答 2查看 1.6K关注 0票数 0

我正在尝试以旧的方式转换执行SQL查询的旧应用程序,如下所示:

代码语言:javascript
复制
java.sql.Connection connection = ....
String queryStr="select acct from Person where acct in (select acct from Document where dbcreate_date > DATEADD(hh,-12, GETDATE())) and status not in ('A','P')";
...
...
java.sql.Statement statement = connection.createStatement(
                ResultSet.TYPE_SCROLL_INSENSITIVE,
                ResultSet.CONCUR_READ_ONLY);
        rs = statement.executeQuery(queryStr);

上面的代码大约需要10毫秒。这包括获取数据库连接、创建语句和执行查询。

我现在使用Hibenate HQL并创建一个HQL查询,如下所示:

代码语言:javascript
复制
Query query = session.createQuery("select p.acct   from Person p  where p.acct in (select  acct from Document d where create_date > :date and status not in ('A','P'))");

现在只需要这条语句"session.createQuery(....)“大约需要105毫秒,这大约是上面提到的用旧方法完成整个查询过程的10倍。

现在我不太确定Hibernate查询缓存是如何工作的,但是如果我再次运行同样的HQL语句,大约需要5毫秒。

现在我的问题是,为什么使用Hibernate HQL会发生这种行为?任何人都知道"session.createQuery(...)“中发生了什么。方法第一次运行的时间要长得多,但第二次运行的时间要短得多?我还注意到,Hibernate在执行"query.list()“时都会对数据库执行SQL。

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-10 07:37:51

尝试在Hibernate中使用原生查询来比较性能:

代码语言:javascript
复制
Query query = session.createSQLQuery("select acct from Person where acct in (select acct from Document where dbcreate_date > DATEADD(hh,-12, GETDATE())) and status not in ('A','P')");

在性能上:

您并不是真的将like与like与您的两个查询进行比较。

您的第一个示例,直接JDBC查询只是一个简单的查询(普通语句)。另一方面,HQL在中有一个参数--所以它会转换成一个JDBC PreparedStatement,这个SQL只编译一次,这样如果你多次调用它,并传递不同的变量值,你就可以快速地运行它。

如果您多次执行这两个查询,您可能会发现HQL查询的平均速度比简单的JDBC查询快。

如果只执行一次,那么简单的JDBC版本可能会比HQL更快,因为HQL最初将被编译。

这里有一些关于Statement vs PreparedStatement的有趣信息:

http://oreilly.com/catalog/jorajdbc/chapter/ch19.html

语句与PreparedStatement语句

人们普遍认为,使用PreparedStatement对象比使用Statement对象更快。毕竟,预准备语句只需针对数据库验证其元数据一次,而语句每次都必须这样做。那么,怎么可能有其他方式呢?问题的真相是,在执行语句的总时间赶上语句之前,它需要大约65次预准备语句的迭代。这对您的应用程序有性能上的影响,本小节主要讨论这些问题。

当谈到哪个SQL statement对象在典型用法下性能更好时,语句还是PreparedStatement,事实是Statement对象产生了最佳性能。当您考虑在应用程序中通常如何使用SQL语句时--这里是1到2个,每个事务可能10-20个(很少更多)--您会意识到,Statement对象执行这些语句所需的时间比PreparedStatement对象要少。

票数 2
EN

Stack Overflow用户

发布于 2012-04-10 05:31:13

您可以使用session.createCriteria来避免解析HQL和构建SQL。

然而,对于复杂的查询,只需在第一次命中时支付一些小的代价(尽管不太可能是~100ms),比构建复杂的createCriteria结构要容易得多。

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10080112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档