|
我对 START WITH TREE.PID = '-1' CONNECT BY TREE.PID = PRIOR ID 不熟悉,下面是我的一点理解:
--原始语句
SELECT SYS_CONNECT_BY_PATH(TREE.INDICATION_ID, '|#|') ID_PATH,
SYS_CONNECT_BY_PATH(TREE.CN_NAME, '|#|') NAME_PATH
FROM
( SELECT ID, PID, INDICATION_ID, EN_NAME,
(SELECT CN_NAME FROM BD_INDICATION_INFO BII WHERE BII. ID = BIT.INDICATION_ID) AS CN_NAME FROM BD_INDICATION_TREE BIT) TREE
WHERE TREE.INDICATION_ID IN('8766119') START WITH TREE.PID = '-1' CONNECT BY TREE.PID = PRIOR ID
---解释:
关于 start with, connect by 语句,我理解的执行计划:语句一开始并不处理 WHERE 段的过滤条件,而是先从 start with 开始,
接着再走 connect by 关系,得到结果集后,再对此结果集走 where 段的条件,这就是为何上面的执行计划的最后一段,会是一团:
|* 9 | HASH JOIN | | 10 | 5731 | 13481 |00:00:00.33 | 12440 | 958K| 958K| 1362K (0)|
| 10 | CONNECT BY PUMP | | 10 | | 13509 |00:00:00.01 | 0 | | | |
| 11 | TABLE ACCESS FULL | BD_INDICATION_TREE | 10 | 13509 | 135K|00:00:00.09 | 12440 | | | |
--------------------------------------------------------------------------------------------------------------------------------------------
因为得在表里搜索/实现这个关系: CONNECT BY TREE.PID = PRIOR ID,此时对两关联字段走 HASH JOIN,应该是最好的选择,
为何不先走 where 段过滤条件,因为走了 where 段的过滤条件,得到的结果集,无法推导出符合这个关系 START WITH TREE.PID = '-1' CONNECT BY TREE.PID = PRIOR ID
的数据(可以把这关系看作一个过滤条件),反之,从 START WITH TREE.PID = '-1' CONNECT BY TREE.PID = PRIOR ID 条件得到的结果集,却可以再用来走
where 段的条件。
但我看不懂第7, 8步骤:
| 7 | TABLE ACCESS BY INDEX ROWID| BD_INDICATION_INFO | 13367 | 1 | 13367 |00:00:00.09 | 26740 | | | |
|* 8 | INDEX UNIQUE SCAN | PK_BD_INDICATION_INFO | 13367 | 1 | 13367 |00:00:00.04 | 13373 | | | |
这是在做什么操作?为何会这么消耗逻辑读?
另外,依照ORACLE的官文对执行计划的执行顺序的解释:先里后外,先上后下,得到的执行顺序是,4,3,6,5,8,7,11,10,9。
但我理解为:应该先 11,10,9,再后面的436587, 也就是,先执行 START WITH TREE.PID = '-1' CONNECT BY TREE.PID = PRIOR ID
再:WHERE TREE.INDICATION_ID IN('8766119'),最后,标量子查询及 SYS_CONNECT_BY_PATH 函数。感觉遇上标量子查询语句时就看不懂。
请指正。 |
|