从上面显示内容可以看出,Hint失效了,还是走IN-List迭代。使用如下两个事件在当前Session中将IN-List迭代禁掉,并将输入参数no_invalidate的值设为false后重新收集一下统计信息,以便后续再次执行上述SQL时不会没用之前走IN-List迭代的执行计划:
zx@MYDB>alter session set events '10142 trace name context forever';
Session altered.
zx@MYDB>alter session set events '10157 trace name context forever';
Session altered.
zx@MYDB>exec dbms_stats.gather_table_stats(ownname=>'SCOTT',tabname=>'EMP',cascade=>true,method_opt=>'for all columns size 1',no_invalidate=>false);
PL/SQL procedure successfully completed.
zx@MYDB>select /*+ USE_CONCAT */ empno,ename from scott.emp where empno in (7654,7698,7782);
EMPNO ENAME
---------- ------------------------------
7654 MARTIN
7698 BLAKE
7782 CLARK
从上述显示内容中可以看出,现在该SQL的执行计划变成了我们想要的IN-List扩展,在执行计划中对应的关键字就是CONCATENATION。这里CONCATENATION的含义就相当于UNION ALL,即上述SQL就相当于UNION ALL改写为如下的形式:
select empno,ename from emp where empno=7782
union all
select empno,ename from emp where empno=7698
union all
select empno,ename from emp where empno=7654
8. CONNECT BY
CONNECT BY是Oracle数据库中层次查询(Hierachical Queries)所对应的关键字,如果出现在执行中也是表示同样的含义。
看一下实例:
zx@MYDB>select empno,ename,job,mgr from scott.emp;
EMPNO ENAME JOB MGR
---------- ------------------------------ --------------------------- ----------
7369 SMITH CLERK 7902
7499 ALLEN SALESMAN 7698
7521 WARD SALESMAN 7698
7566 JONES MANAGER 7839
7654 MARTIN SALESMAN 7698
7698 BLAKE MANAGER 7839
7782 CLARK MANAGER 7839
7788 SCOTT ANALYST 7566
7839 KING PRESIDENT
7844 TURNER SALESMAN 7698
7876 ADAMS CLERK 7788
7900 JAMES CLERK 7698
7902 FORD ANALYST 7566
7934 MILLER CLERK 7782
从上述内容可以看到KING是PRESIDENT,它所在记录的MGR的值为NULL,表示KING没有上级。
我们执行如下SQL,��KING所在的记录开始,将所有人按照上下级关系分成显示出来:
zx@MYDB>select empno,ename,mgr from emp start with empno=7839 connect by prior empno=mgr;
EMPNO ENAME MGR
---------- ------------------------------ ----------
7839 KING
7566 JONES 7839
7788 SCOTT 7566
7876 ADAMS 7788
7902 FORD 7566
7369 SMITH 7902
7698 BLAKE 7839
7499 ALLEN 7698
7521 WARD 7698
7654 MARTIN 7698
7844 TURNER 7698
7900 JAMES 7698
7782 CLARK 7839
7934 MILLER 7782
查看执行计划: