注意到上述显示内容中id=2的执行步骤所对应的列A-Rows的值为3,id=3的执行步骤所对应的列Starts的值为2,说明虽然全表扫描T1所得到的驱动结果集的数量为3,但走Filter类型的执行计划时访问被驱动表T2的实际次数却不是3,而是2.这是因为表T数量虽然是3,但其列COL2的distinct值的数量却只有2,所以在用过滤条件“where col2 in(select /*+ no_unnest */ col2 from t2)”去过滤表T1中的数据时,只用访问两次表T2就可以了。
5. SORT
SORT就是排序的意思,执行计划中的SORT通常会以组合的方式出现,这些组合方式包括但不限于如下这几种:
SORT AGGREGATE
SORT UNIQUE
SORT JOIN
SORT GROUP BY
SORT ORDER BY
BUFFER SORT
执行计划中即使出现了关键字“SORT”,也不一定意味着就需要排序,比如SORT AGGREGATE和BUFFER SORT就不一定需要排序。
看一个实例,还是使用上面的EMP_TEMP表:
zx@MYDB>set autotrace traceonly
zx@MYDB>select sum(sal) from emp_temp where job='MANAGER';
从上述显示内容可以看出,现在SQL的执行计划走的是SORT AGGREGATE,这里执行的SQL只是求了一个sum值,很显然这里不需要排序的。统计信息中的sort(memroy)和sort(disk)的值均为0,也说明Oracle在执行此SQL时并没有做任何排序操作,所以我们说SORT AGGREGATE并不一定需要排序,这其中的关键字“SORT”具有一定的迷惑性。
下面再做实例:
zx@MYDB>set autotrace off
zx@MYDB>select distinct ename from emp_temp where job='MANAGER' order by ename;
ENAME
------------------------------
BLAKE
CLARK
JONES
上述SQL的含义是既要排序又要去重,它对应的执行计划就会是SORT UNIQUE
zx@MYDB>select /*+ use_merge(t1 t2) */t1.empno,t1.ename,t2.sal from scott.emp t1,emp_temp t2 where t1.empno=t2.empno;
从上述显示内容中可以看出,现在该SQL的执行计划走的是对EMP和EMP_TEMP的排序合并连接。SORT JOIN类型的执行计划通常会出现在排序合并连接中,它是排序合并连接所对应的执行计划第一步要做的事情。
再执行如下SQL:
zx@MYDB>select ename from emp_temp where job='MANAGER' order by ename;
ENAME
------------------------------
BLAKE
CLARK
JONES
上述SQL的含义是只需要单纯的排序,它对应的执行计划就会是SORT ORDER BY:
接着执行下面的SQL:
select ename from emp_temp where job='MANAGER' group by ename order by ename;
ENAME
------------------------------
BLAKE
CLARK
JONES
上述SQL的含义是既要排序又要分组,所以它对应的执行计划就会是SORT GROUP BY: