关于hibernate分页的效率问题

今天在做hibernate分页的时候有个人在看到我后台报的sql语句时跟我说这个是假分页,sql语句是这样的select * from (select row_.*,rownum rownum_ from (select t.* from user_view t) row_) where rownum_ <= 20 and rownum_ > 10,他跟我说首先执行了里面的语句查询出了所有的东西然后在执行了外面的语句,然后他说真分页应该是这样的select * from (select rownum rn,a.name from user_view a where rownum <=20) t where t.rn >= 10,然后他把这两条语句放到plsql的sql执行窗口里面执行了解释计划,跟我说第一条语句的基数是表里所有的记录数,第二条语句的基数是20,这说明了计算机在执行第一条语句的时候是先查出了所有的东西。但是我执行了这两条语句其实耗时是差不多的,但是他说在本机的查询看不出效率的差别,要连外部的数据库查询才能看出效率差别,我想全世界那么多人在用hibernate真分页,不会都被忽悠了吧,我该怎么反驳这个事情。我上传了截图

gc00001
gc00001 那个人又跟我说上次出差拨了vpn执行这两条sql结果执行时间一个是6秒一个是1秒,等过几天有个同事出差我也叫他做一下这个实验试一下是否时间上差这么多
6 年多之前 回复

4个回答

1.肯定一下,那个告诉你是假分页的人是正确的,通过你打印的SQL应该是假分页。因为在内层已经查询了全部select t.* from user_view t 这个地方没有分页。正确的写法是那个人告诉你的写法。

2.效率问题是因为你的基数不够大,可以尝试下数据库单表100W数据量,然后你在对比下两个SQL的效率,答案是肯定的。第二个效率肯定高。

3.hibernate对各种数据库方言分页的写法可以参看:http://my-corner.iteye.com/blog/721903

gc00001
gc00001 我看了下你提供的网页,刚才经过对楼下自动优化机制的研究,发现你提供的网页中说到的oracle9i生成的三层嵌套的分页是有问题的,第二层的rownum <= ?会自动放到内层中去,导致和内层中orderby语句在一起,产生先rownum <= ?在排序的问题,可能9i没有这种自动优化机制吧,反正hibernate生成的10g分页方言是将rownum>?和rownum<?都放在第三层这样就不会有自动优化的功能,也就是正常的先排序在分页,这些sql语句我都在10g的oracle上实验过了,9i生成的三层嵌套语句在10g里面是有问题的
6 年多之前 回复
gc00001
gc00001 那个人是公司的ocm,看来还是他说对了,是不是说hibernate对于oracle封装的分页语句其实是伪分页?
6 年多之前 回复

问题很有迷惑性,由于知识面过窄造成的误解,oracle强大的功能之一就是对sql进行自动优化,执行效率最高的sql,这个分页中 oracle会自动把外层的条件放到内层去提高sql的执行效率,详细介绍可以参考:[url]http://wenku.baidu.com/view/db92f8ef102de2bd960588ae.html[/url]

gc00001
gc00001 我仔细看了,刚刚实验了下,我拨了vpn连接外部数据库,测了一个有40W行数据的表分别用了你的两种查询语句,确实有速度上的提升,第一种花了0.6s,第二种花了0.9s,但是hibernate生成的sql语句却是使用的比较慢的第二种,后来我发现如果加上order by 语句,这种cbo优化机制会产生弊端,优化机制自动把第二层的ROWNUM <= 40嵌入到第一层的带有order by的语句中,这样就导致了先执行ROWNUM <= 40再去排序,这显然不是我要的结果,怪不得hibernate使用了第二种比较慢的,原来是考虑到orderby的关系,我觉得这种优化机制不好,外层条件自动放到内层会让本来应该先排序在分页的语句变成了先分页在排序
6 年多之前 回复

看不出差别是数据量还不够多 数据量少的话肯定看不出差别 楼上说的对 你把数据库的数据增加到过百万行的数据 不同测试工具 你自己都能感觉出来。

gc00001
gc00001 刚才拨vpn连接外部数据库,测了一个有40W行数据的表,确实两条语句差了很多的时间,但是却必须要使用慢的那条语句,因为有order by的情况下使用select * from (select rownum rn,a.name from user_view a where rownum <=20 order by aid) t where t.rn >= 10会导致先rownum <=20在排序
6 年多之前 回复

分页不是用limit吗?

iteye_15034
iteye_15034 谢谢,学习了
6 年多之前 回复
gc00001
gc00001 limit好像只有mysql能用
6 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!