今天无意间看了一个文章,文章里这个面试官说他在面试的时候一般都会问两个问题:
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的基础上加去重加默认排序
执行计划看这图:
<li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true"> <use xlink:href="#csdnc-thumbsup"></use> </svg><span class="name">点赞</span> <span class="count"></span> </a></li> <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-Collection-G"></use> </svg><span class="name">收藏</span></a></li> <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-fenxiang"></use> </svg>分享</a></li> <!--打赏开始--> <!--打赏结束--> <li class="tool-item tool-more"> <a> <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg> </a> <ul class="more-box"> <li class="item"><a class="article-report">文章举报</a></li> </ul> </li> </ul> </div> </div> <div class="person-messagebox"> <div class="left-message"><a href="https://blog.csdn.net/u014710633"> <img src="https://profile.csdnimg.cn/6/6/4/3_u014710633" class="avatar_pic" username="u014710633"> <img src="https://g.csdnimg.cn/static/user-reg-year/2x/6.png" class="user-years"> </a></div> <div class="middle-message"> <div class="title"><span class="tit"><a href="https://blog.csdn.net/u014710633" data-report-click="{"mod":"popu_379"}" target="_blank">jzzw</a></span> </div> <div class="text"><span>发布了89 篇原创文章</span> · <span>获赞 11</span> · <span>访问量 3万+</span></div> </div> <div class="right-message"> <a href="https://im.csdn.net/im/main.html?userName=u014710633" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信 </a> <a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a> </div> </div> </div>