Oracle中Order by和rownum执行先后顺序的问题

今天无意间看了一个文章,文章里这个面试官说他在面试的时候一般都会问两个问题:

1.order by和rownum执行顺序的问题
2.union和union all的区别

union和union all的区别这个我知道,区别在于去不去重(这个地方有问题,下面说),order by和rownum执行顺序的问题这个我还真不知道,所以说想研究一下

网上查了一下。比较靠谱的说法是order by涉及到索引列的先order by再rownum,order by涉及到普通列的话先rownum再order by

然后实际测试一下发现,上面的描述也不对。

那么如何来确认order by和rownum的执行顺序呢,我在测试过程中突然想到了一个思路,那就是看执行计划

给大家贴两个执行计划,大家就看明白了(我这是plsql里面F5生成的执行计划,不一定是sql的真正的执行计划)

看到区别了么,尤其是红框部分:

第一个走的是index full scan,然后count stopkey,众所周知索引是有序的,且count stopkey其实就是sql的rownum操作,所以说第一个sql是先进行的order by,再进行的rownum

第二个走的是 table access full,然后count stopkey,然后sort order by,这就更明确了,先全表扫,再rownum,再order by

所以当遇到这种情况,我们只能通过看执行计划来确定,没有什么万能的规律

所以说我们SQL里面如果想写成先order by再rownum的逻辑,最好的方式就是使用row_number() over (order by xxx)加嵌套查询的模式。

 

 

在上面的实验过程后我顺便看了一下union和union  all的执行计划,我发现了一个情况,那就是union的sql的执行计划的最外层有一个sort unique操作!! 也就是说union就相当于是union all+sort unique,也就是说union是union all的基础上加去重加默认排序

执行计划看这图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值