首页 / 数据库 / MySQL / Oracle递归查询的原理
在Oracle 10g下,来到scott用户下,分别以层次 1,2,3,4上的节点做实验: 当start with是根节点(level=1),要查其子节点,connect by pump和emp都是被扫描4次(总的层次)。 当start with是根节点(level=2),要查其子节点,connect by pump和emp被扫描3次。 当start with是根节点(level=3),要查其子节点,connect by pump和emp被扫描2次。当start with是根节点(level=4),要查其子节点,connect by pump和emp被扫描1次。注意的是:leve=2,level=3不是叶子节点,如果是叶子节点,那connect by pump和emp只扫描一次。 Operation Name Starts FILTER TABLE ACCESS FULL EMP 1 HASH JOIN CONNECT BY PUMP 4 TABLE ACCESS FULL EMP 4我来解读上面的执行计划,以start with ename = "KING"为例,显示对EMP通过"ENAME"="KING"过滤找到节点作为根节点(集合A),通过集合A到下一级所有满足条件的节点(集合B),通过集合B再到下一级所有满足条件的节点(集合C),树有几级就CONNECT BY PUMP几次。Oracle 函数中游标及递归的应用 http://www.linuxidc.com/Linux/2014-06/103553.htmOracle递归函数 http://www.linuxidc.com/Linux/2014-06/102687.htmOracle 递归查询 http://www.linuxidc.com/Linux/2013-06/85879.htmOracle递归START WITH...CONNECT BY PRIOR子句用法 http://www.linuxidc.com/Linux/2013-01/78585.htmOracle 使用递归的性能提示 http://www.linuxidc.com/Linux/2013-01/78541.htmOracle递归查询(start with) http://www.linuxidc.com/Linux/2012-11/74736.htm SQL> set pagesize 100 SQL> --根节点 level=1 SQL> select e.empno, e.ename, e.mgr, e.deptno,level from emp e start with ename = "KING" connect by prior empno = mgr; EMPNO ENAME MGR DEPTNO LEVEL ---------- ---------- ---------- ---------- ---------- 7839 KING 10 1 7566 JONES 7839 20 2 7788 SCOTT 7566 20 3 7876 ADAMS 7788 20 4 7902 FORD 7566 20 3 7369 SMITH 7902 20 4 7698 BLAKE 7839 30 2 7499 ALLEN 7698 30 3 7521 WARD 7698 30 3 7654 MARTIN 7698 30 3 7844 TURNER 7698 30 3 7900 JAMES 7698 30 3 7782 CLARK 7839 10 2 7934 MILLER 7782 10 3 已选择14行。 SQL> select * from table(dbms_xplan.display_cursor(null,null,"allstats last")); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- SQL_ID 6as71p9t5arg3, child number 0 ------------------------------------- select e.empno, e.ename, e.mgr, e.deptno,level from emp e start with ename = "KING" connect by prior empno = mgr Plan hash value: 3364448299 ----------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ----------------------------------------------------------------------------------------------------------------------- |* 1 | CONNECT BY WITH FILTERING| | 1 | | 14 |00:00:00.01 | 35 | 9216 | 9216 | 8192 (0)| |* 2 | FILTER | | 1 | | 1 |00:00:00.01 | 7 | | | | | 3 | TABLE ACCESS FULL | EMP | 1 | 14 | 14 |00:00:00.01 | 7 | | | | |* 4 | HASH JOIN | | 4 | | 13 |00:00:00.01 | 28 | 1036K| 1036K| 776K (0)| | 5 | CONNECT BY PUMP | | 4 | | 14 |00:00:00.01 | 0 | | | | | 6 | TABLE ACCESS FULL | EMP | 4 | 14 | 56 |00:00:00.01 | 28 | | | | | 7 | TABLE ACCESS FULL | EMP | 0 | 14 | 0 |00:00:00.01 | 0 | | | | ----------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("ENAME"="KING") 2 - filter("ENAME"="KING") 4 - access("MGR"=NULL) SQL> --level=2 SQL> select e.empno, e.ename, e.mgr, e.deptno,level from emp e start with ename = "JONES" connect by prior empno = mgr; EMPNO ENAME MGR DEPTNO LEVEL ---------- ---------- ---------- ---------- ---------- 7566 JONES 7839 20 1 7788 SCOTT 7566 20 2 7876 ADAMS 7788 20 3 7902 FORD 7566 20 2 7369 SMITH 7902 20 3 SQL> select * from table(dbms_xplan.display_cursor(null,null,"allstats last")); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------ SQL_ID 2bcjwvmbyg7a5, child number 1 ------------------------------------- select e.empno, e.ename, e.mgr, e.deptno,level from emp e start with ename = "JONES" connect by prior empno = mgr Plan hash value: 3364448299 ----------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ----------------------------------------------------------------------------------------------------------------------- |* 1 | CONNECT BY WITH FILTERING| | 1 | | 5 |00:00:00.01 | 28 | 9216 | 9216 | 8192 (0)| |* 2 | FILTER | | 1 | | 1 |00:00:00.01 | 7 | | | | | 3 | TABLE ACCESS FULL | EMP | 1 | 14 | 14 |00:00:00.01 | 7 | | | | |* 4 | HASH JOIN | | 3 | | 4 |00:00:00.01 | 21 | 1036K| 1036K| 404K (0)| | 5 | CONNECT BY PUMP | | 3 | | 5 |00:00:00.01 | 0 | | | | | 6 | TABLE ACCESS FULL | EMP | 3 | 14 | 42 |00:00:00.01 | 21 | | | | | 7 | TABLE ACCESS FULL | EMP | 0 | 14 | 0 |00:00:00.01 | 0 | | | | ----------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("ENAME"="JONES") 2 - filter("ENAME"="JONES") 4 - access("MGR"=NULL) SQL> --level=3 SQL> select e.empno, e.ename, e.mgr, e.deptno,level from emp e start with ename = "SCOTT" connect by prior empno = mgr; EMPNO ENAME MGR DEPTNO LEVEL ---------- ---------- ---------- ---------- ---------- 7788 SCOTT 7566 20 1 7876 ADAMS 7788 20 2 SQL> select * from table(dbms_xplan.display_cursor(null,null,"allstats last")); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------------------------------- SQL_ID fqf7r75c9atqv, child number 0 ------------------------------------- select e.empno, e.ename, e.mgr, e.deptno,level from emp e start with ename = "SCOTT" connect by prior empno = mgr Plan hash value: 3364448299 ----------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ----------------------------------------------------------------------------------------------------------------------- |* 1 | CONNECT BY WITH FILTERING| | 1 | | 2 |00:00:00.01 | 21 | 9216 | 9216 | 8192 (0)| |* 2 | FILTER | | 1 | | 1 |00:00:00.01 | 7 | | | | | 3 | TABLE ACCESS FULL | EMP | 1 | 14 | 14 |00:00:00.01 | 7 | | | | |* 4 | HASH JOIN | | 2 | | 1 |00:00:00.01 | 14 | 1036K| 1036K| 282K (0)| | 5 | CONNECT BY PUMP | | 2 | | 2 |00:00:00.01 | 0 | | | | | 6 | TABLE ACCESS FULL | EMP | 2 | 14 | 28 |00:00:00.01 | 14 | | | | | 7 | TABLE ACCESS FULL | EMP | 0 | 14 | 0 |00:00:00.01 | 0 | | | | ----------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("ENAME"="SCOTT") 2 - filter("ENAME"="SCOTT") 4 - access("MGR"=NULL) SQL> --level=4 SQL> select e.empno, e.ename, e.mgr, e.deptno,level from emp e start with ename = "SMITH" connect by prior empno = mgr; EMPNO ENAME MGR DEPTNO LEVEL ---------- ---------- ---------- ---------- ---------- 7369 SMITH 7902 20 1 SQL> select * from table(dbms_xplan.display_cursor(null,null,"allstats last")); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------------------------------- SQL_ID f5fvjuk1j8mak, child number 1 ------------------------------------- select e.empno, e.ename, e.mgr, e.deptno,level from emp e start with ename = "SMITH" connect by prior empno = mgr Plan hash value: 3364448299 ----------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ----------------------------------------------------------------------------------------------------------------------- |* 1 | CONNECT BY WITH FILTERING| | 1 | | 1 |00:00:00.01 | 14 | 9216 | 9216 | 8192 (0)| |* 2 | FILTER | | 1 | | 1 |00:00:00.01 | 7 | | | | | 3 | TABLE ACCESS FULL | EMP | 1 | 14 | 14 |00:00:00.01 | 7 | | | | |* 4 | HASH JOIN | | 1 | | 0 |00:00:00.01 | 7 | 1036K| 1036K| 318K (0)| | 5 | CONNECT BY PUMP | | 1 | | 1 |00:00:00.01 | 0 | | | | | 6 | TABLE ACCESS FULL | EMP | 1 | 14 | 14 |00:00:00.01 | 7 | | | | | 7 | TABLE ACCESS FULL | EMP | 0 | 14 | 0 |00:00:00.01 | 0 | | | | ----------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("ENAME"="SMITH") 2 - filter("ENAME"="SMITH") 4 - access("MGR"=NULL)更多Oracle相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12本文永久更新链接地址
收藏该网址