java – 使用HQL的Hibernate分页
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 使用HQL的Hibernate分页,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4271字,纯文字阅读大概需要7分钟。
内容图文
![java – 使用HQL的Hibernate分页](/upload/InfoBanner/zyjiaocheng/815/d9676c2f93224e9b8fcdc1e1c297c1b0.jpg)
Hibernate分页问题
我有一个与Hibernate分页有关的问题,并且在某种程度上已经解释了这个问题
Using Hibernate’s ScrollableResults to slowly read 90 million records
Issues with Pagination and Sorting
细节
来自应用程序的HQL查询:
Query q = session.createQuery("from RequestDao r order by r.id desc");
q.setFirstResult(0);
q.setMaxResults(50);
查询返回300万条记录,对于分页,我们只设置了50条记录,分页页面非常慢,因为在每次刷新时我们都会调用查询来获取3百万条记录,而我们只设置50条记录.
我的主要问题是
Does HQL always goes and hits database or does it go and hit session or memory to look for the data and if it goes everytime to hit database and get resultset then it is very proper from performance point of view, what would be best solutions to improve it?
在hibernate中使用HQL有一种方法可以查询数据库并首先获取50条记录,然后根据用户的要求获取其他记录.这个挑战真的让应用程序陷入困境,那么解决这个问题的最佳方法是什么呢?
在日志中生成的HQL查询
from com.delta.dao.RequestDao r order by r.id desc
Hibernate生成的查询
select
getrequest0_.ID as ID24_,
getrequest0_.TIME as START3_24_,
getrequest0_.STAT as STATUS24_,
getrequest0_.SUM as SUMMARY24_,
getrequest0_.OUTNAME as OUTPUT7_24_,
getrequest0_.INPNAME as INPUT8_24_,
getrequest0_.REQUEST_DATE as requestT9_24_,
getrequest0_.PARENT_ID as PARENT10_24_,
getrequest0_.INTER_TYPE as INTERPO60_24_,
getrequest0_.OPEN_INT as OPEN61_24_,
getrequest0_.SOURCE_TYPE as SOURCE62_24_,
getrequest0_.TARGET_TYPE as TARGET20_24_,
getrequest0_.SOURCE as SOURCE14_24_,
getrequest0_.COPY_DATA as COPY16_24_,
getrequest0_.CURVE as GENERATE63_24_,
getrequest0_.TITLE as TITLE24_,
getrequest0_.TIME_ID as TIMESERIES12_24_,
getrequest0_.TASK_NAME as TASK51_24_
from
REQUEST getrequest0_
where
getrequest0_.KIND='csv'
order by
getrequest0_.ID desc
以下是查询的解释计划:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | | 1 | SIMPLE | getrequest0_ | ref | TR_KIND_ID | TR_KIND_ID | 6 | const | 1703018 | 100.00 | Using where |
附加信息:在50个记录限制上查询带有和不带order by子句的运行时间
如果我使用order子句运行查询,那么查询需要0.0012s并设置LIMIT 50且没有order子句,同一查询需要0.0032s且具有相同的LIMIT 50.
另外,我们如何找到:
>特定的HQL查询是在点击数据库而不是缓存或从会话中获取信息?
> HQL查询是否总是会命中数据库以获得结果,而Criteria会进入会话或缓存并从中获取结果?
>还在我下面提到的查询中:
a) Query q = session.createQuery("from RequestDao r order by r.id desc");
b) q.setFirstResult(0);
c) q.setMaxResults(50);
在a,我们从数据库获得结果并将其存储在内存中,或者如果没有,并且此时我们在结果集中有300万个结果,然后在b和c我们设置偏移值并限制在页面上我们会这样,这是真的吗?只看到50个结果,所以现在剩下3百万条记录,在我们第二次调用这个查询时,我们再次进入数据库并获取300万条记录并将它们放入内存然后在c再次设置50条记录并继续上.
这个问题对我来说并不清楚,因此如果有人能够提供明确而详细的解释,说明这是如何工作的,以及什么是解决这个问题的最佳解决方案,我们将非常感激.
更新
事实证明,问题与页面上的记录显示无关,但我在该页面上有过滤器,并且每次请求都会从数据库中再次获取所有下拉值,并且在那里有一些时髦的事情发生在那里导致页面加载时间增加.
我正在对数据库进行多个嵌套的hibernate查询并获得结果,这个问题的最佳解决方案是什么?
解决方法:
您的查询告诉数据库对所有满足WHERE子句的记录进行排序.它有可能在返回前50之前对数百万条记录进行排序.
编辑1/26:现在澄清了具体问题,我将尝试更具体地回答.
>每次执行这样的查询时,Hibernate都会进入数据库.更重要的是,它会将会话中的所有新/更新数据刷新到磁盘.如果这是您的情况,此行为可能会导致缓慢.
>使用Hibernate查询API通常在大多数情况下都能很好地运行,并且与各种各样的数据库平台兼容.如果您真的担心从数据访问层中挤出最后一滴性能,您可以编写自己的本机SQL查询来选择前50个结果.但是一旦你这样做,你几乎肯定会失去数据库独立性.因此,评估您的成本与收益.
您的查询运行时间似乎在单毫秒范围内.这通常与在磁盘上存储数据的关系数据库一样好.所以你可能想评估一下你是否确实遇到了性能问题.
编辑1/27:好的.它看起来像页面整体设计中的问题.我在过去7年左右一直在使用AJAX,所以我通常不必等待过滤UI控件在浏览表格时重绘.我想,在您的情况下,切换应用程序UI框架不是一个选项.您必须弄清楚如何优化下拉列表等数据的加载.这些数据经常变化吗?你可以在应用程序的某个地方缓存它吗?如果你每次都必须加载它们,你能否只是获取显示字符串而不是整个对象?
内容总结
以上是互联网集市为您收集整理的java – 使用HQL的Hibernate分页全部内容,希望文章能够帮你解决java – 使用HQL的Hibernate分页所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。