日期:2014-05-16  浏览次数:20452 次

关于distinct和group by的效率问题
一直以来都有这么个疑问,关于distinct和group by的效率问题

比如下面这个2个语句:
select distinct type from BBTEST;

select type from BBTEST group by type

两个语句的结果是一样的,就是取出表中的type值,去处重复记录。
但是这两者的执行效率如何呢,是否有差异?

在10gR2以前,distinct走的是SORT UNIQUE,group by走的是SORT GROUP BY,两者都需要进行排序;
10gR2以后,默认情况下distinct改走HASH UNIQUE,group by走HASH GROUP BY(至少在上面的简单例子中肯定是这样的)


测试例子:
BBTEST表有100万行,type字段上有索引。
多次执行后,统计信息固定输出如下:

SQL> select distinct type from bbtest;

T
-
1
3
6
8
7
5
9
4
2

已选择9行。

已用时间:  00: 00: 00.23
执行计划
----------------------
Plan hash value: 3426129975
--------------------------------------------

| Id  | Operation          | Name   | Rows  | Bytes |TempSpc| Cost (%CPU)| Time    |

--------------------------------------------
|   0 | SELECT STATEMENT   |        |   958K|  2808K|       |  3790   (6)| 00:00:46 |
|   1 |  HASH UNIQUE       |        |   958K|  2808K|    22M|  3790   (6)| 00:00:46 |
|   2 |   TABLE ACCESS FULL| BBTEST |   958K|  2808K|       |  1098   (4)| 00:00:14 |
--------------------------------------------

Note
-----
   - dynamic sampling used for this statement


统计信息
----------------------
          0  recursive calls
          0  db block gets
       4850  consistent gets
          0  physical reads
          0  redo size
        490  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          9  rows processed


SQL> select type from bbtest group by type;

T
-
1
8
5
2
3
6
7
9
4

已选择9行。

已用时间:  00: 00: 00.25

执行计划
----------------------
Plan hash value: 19366041

-----------------------------------------
| Id  | Operation          | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------
|   0 | SELECT STATEMENT   |        |   958K|  2808K|  1247  (15)| 00:00:15 |
|   1 |  HASH GROUP BY     |        |   958K|  2808K|  1247  (15)| 00:00:15 |
|   2 |   TABLE ACCESS FULL| BBTEST |   958K|  2808K|  1098   (4)| 00:00:14 |
-----------------------------------------

Note
-----
   - dynamic sampling used for this statement


统计信息
----------------------
          0  recursive calls
          0  db block gets
       4850  consistent gets
&nb