Oracle的分页、排序、效率问题

一、数据准备

select count(*) from order_detail_info;

二、分页方式--between and

前提:Oracle是使用rownum分页,它是一个伪列,用于标记行号。下面就使用rownum进行分页查询(错误示范): 

select * from order_detail_info where rownum>=2 and rownum <= 8;

执行sql之后发现并无查询结果集,这是为什么?rownum相当于一个动态的伪列,它总是从1开始,而查询条件是rownum>=2,第一条记录不满足条件,排除第一条记录以后,第二条记录的rownum又变成了1,依次类推,所以永远不能满足rownum>2这个条件,这也就是查询不到结果的原因。那么正确的用法就是先将rownum查询出来作为单独的一列,然后再添加判断条件即可。

select t.*
  from (select rownum rn, o2.*
          from order_detail_info o2
         where o2.register_id = '437577094') t
 where t.rn between 2 and 6
--耗时0.031s

三、分页方式--<=&&>

3.1:不带排序的分页查询

select t.*
  from (select rownum rn, o2.*
          from order_detail_info o2
         where o2.register_id = '437576875' and rownum<=6) t
 where t.rn>=2
--耗时0.016s

这里要着重说明:从sql执行耗时来看,使用<= >分页方式的查询效率普遍比使用between and的效率要高。原因如下:对于方式二的分页查询,rownum<=6可以被oracle推入到内层循环中,一旦查询结果不满足rownum<=6,就终止查询将结果返回了,也就是说最内层内存查询出了6条满足条件的数据;而对于方式一的查询,由于查询条件between 2 and 6是存在于最外层,它的最内层是查询所有满足条件的数据(查询出的数据可能很多),只是在最外层做了条件筛选,显然这个效率要比方式二低很多。日常使用推荐方式二。

3.2带排序的分页查询

如果我们想要实现又要排序,又有分页的功能,例3.1的查询结果按照order_deatil_id进行排序。做法是先在内层循环排序,然后再进行分页筛选,只是比不带分页的查询多嵌套了一层。

select tt.*
  from (select rownum rn, t.*
          from (select o2.*
                  from order_detail_info o2
                 where o2.register_id = '437576875'
                 order by o2.order_detail_no desc) t
         where rownum <= 6) tt
 where tt.rn >= 2

四、分组分页排序混合使用

面试题:每个部门工资前三高的员工。

这里使用Oracle的row_number() OVER (PARTITION BY COL1 ORDER BY COL2)函数,该函数表示根据COL1分组,在分组内部根据COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号。它与rownum的区别在于:使用rownum进行排序的时候是先将伪列加入结果集然后在排序;而此函数在包含排序从句后是先排序再计算行号码

select deptno, ename, sal
  from (select deptno,
               ename,
               sal,
               row_number() over(partition by deptno order by sal desc) as sal_order
          from scott.emp)
 where sal_order <= 3;

五、分页排序导致数据重复问题。

问题描述:公司项目有一个查询会员信息的功能,数据来源于会员表,会员表中有一个字段叫会员等级,其值为三省、四星、五星、普通会员。该查询功能首先是按照会员等级进行排序,然后再分页,问题就出现了,在页面上点击分页查看信息时,会发现其中某两页的数据有重复。定位问题,发现是在排序和分页一起使用时,所排序的列必须具有唯一性,因为会员等级会有重复,所以导致查询出的结果也会有重复数据。解决办法:按照具有唯一性属性的列排序。做个记录。

参考文章:

原文:https://blog.csdn.net/u011278012/article/details/52024843
原文:https://blog.csdn.net/imliuqun123/article/details/79535871

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值