陈辉
作者陈辉·2012-08-24 14:46
研发工程师·IBM

关于order by fetch first 1 rows only和MAX()函数的区别

字数 1299阅读 9739评论 0赞 0
某客户问了我个有趣的问题:SQL1:select balance from acct order by balance desc FETCH FIRST 1 ROWS ONLY 用时0m8.229s. ; SQL2: select MAX(balance) from acct却只用时0m2.509s.;
这两个SQL所达到的功能是一样的,为什么时间相差这么大?我居然研究了一天,有意思!

我在自己的环境下做了个实验,对比了以下两个SQL
SQL1:用时0m8.229s
select balance  
from acct
order by balance  desc
FETCH FIRST 1 ROWS ONLY;

SQL2:用时0m2.509s
select MAX(balance)  from acct;

说明order by fetch first和MAX()确实有差别,

然后我利用db2trc将内部各个函数所消耗的时间打印出来,进行比较发现大部分的函数都相同,只有如下差别
SQL1特有的函数:
1000000    (50 sec, 271418000 nanosec)     sqlrisr2
1000000    (4 sec, 170279000 nanosec)     sqlsBuildRow
1000000    (40 sec, 999689000 nanosec)     sqlrsinsr
1000000    (4 sec, 730063000 nanosec)     sqlsorti
1000000    (31 sec, 588936000 nanosec)     sqlsinsr

SQL2特有的函数:
1000001    (4 sec, 144051000 nanosec)     sqlrimax
1000000    (13 sec, 790593000 nanosec)     sqlriag2

在order by fetch first中,所有的记录必须从磁盘取出来放入一个叫insert buffer的内部结构,然后进行排序,按照常识我们知道一般树排序的复杂度为O(nlogn), 最好的基数排序的复杂度是O(n),但是也需要额外生成许多复杂的数据结构。

而在MAX()语句中,只是使用了sqlrimax来从n个记录中取最大值,这n个记录从磁盘中取出来后,不用插入insert buffer进行排序,只需要依次和最大值进行比较,如果小于,则丢弃。算法复杂度为O(n),不需要额外的复杂结构。因此速度比SQL1要快。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

X社区推广