SQL。递归查询。如何优化此查询?

时间:2012-11-23 08:29:07

标签: sql oracle caching recursion

有没有办法优化递归查询?

表:

TREE_TABLE: 
      Parent   varchar2 
      Child    varchar2
TABLEXXX:   
      FieldXXX varchar2       

我需要获得所有具有TABLEXXX(FieldXXX)中具有引用的子项的根。 查询结果是正确的,但响应时间太长。 可以减少对子查询的访问次数吗?或者另一个提示...

TREE_TABLE(树格式)

a - b - c
d
f - g

TABLEXXX

c
f

结果:

a
b
c
f


-- Cost: 7. Bytes: 33.210  Cardinality: 1.230 
WITH subquery AS
(SELECT FIELD FROM TABLEXXX WHERE ...)
SELECT CONNECT_BY_ROOT t1.CHILD "ROOT"
   FROM TREE_TABLE t1
    WHERE EXISTS
      (SELECT subquery.FIELD 
        FROM subquery
        WHERE t1.CHILD = subquery.FIELD)
    START WITH t1.CHILD IN
                  (SELECT FIELD FROM TABLEYYYY WHERE ...)
    CONNECT BY PRIOR t1.CHILD = t1.PARENT

执行计划

 <ExplainPlan>
   <PlanElement id="0" operation="SELECT STATEMENT" optimizer="ALL_ROWS" cost="7" cardinality="1.230" bytes="33.210" cpu_cost="3.583.764" io_cost="6">
     <PlanElements>
       <PlanElement id="1" operation="FILTER" filter_predicates=" EXISTS (SELECT 0 FROM &quot;TS_SO_ENG_VALUATIONS_INFO&quot; &quot;V&quot; WHERE &quot;V&quot;.&quot;VAL_DATE&quot;=TO_DATE('2012-10-31 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND &quot;V&quot;.&quot;CLIENT_CP_CODE&quot;=:B1 GROUP BY &quot;CLIENT_CP_CODE&quot;)">
         <PlanElements>
           <PlanElement id="2" operation="CONNECT BY" option="WITH FILTERING" filter_predicates=" EXISTS (SELECT 0 FROM &quot;TS_BPU_EMAIL_EXTRA_INFO&quot; &quot;TS_BPU_EMAIL_EXTRA_INFO&quot; WHERE &quot;COUNTERPARTY&quot;=:B1)">
       <PlanElements>
         <PlanElement id="3" operation="FILTER" filter_predicates=" EXISTS (SELECT 0 FROM &quot;TS_BPU_EMAIL_EXTRA_INFO&quot; &quot;TS_BPU_EMAIL_EXTRA_INFO&quot; WHERE &quot;COUNTERPARTY&quot;=:B1)">
           <PlanElements>
             <PlanElement id="4" operation="COUNT">
         <PlanElements>
           <PlanElement id="5" operation="HASH JOIN" option="RIGHT OUTER" cost="7" cardinality="1.230" bytes="33.210" cpu_cost="3.583.764" io_cost="6" access_predicates="&quot;T2&quot;.&quot;COUNTERPARTY&quot;(+)=&quot;T1&quot;.&quot;FATHER&quot;">
             <PlanElements>
               <PlanElement object_ID="0" id="6" operation="INDEX" option="FAST FULL SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="IDX_TS_BPU_EMAIL_FAMILY_CNT" object_type="INDEX" cost="3" cardinality="1.230" bytes="12.300" cpu_cost="176.086" io_cost="3"/>
               <PlanElement object_ID="1" id="7" operation="INDEX" option="FAST FULL SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="TS_BPU_EMAIL_FAMILY_PK" object_type="INDEX (UNIQUE)" cost="3" cardinality="1.230" bytes="20.910" cpu_cost="190.329" io_cost="3"/>
             </PlanElements>
           </PlanElement>
         </PlanElements>
             </PlanElement>
             <PlanElement object_ID="2" id="8" operation="INDEX" option="UNIQUE SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="TS_BPU_EMAIL_EXTRA_INFO_PK" object_type="INDEX (UNIQUE)" search_columns="1" cost="1" cardinality="1" bytes="10" cpu_cost="14.443" io_cost="1" access_predicates="&quot;COUNTERPARTY&quot;=:B1"/>
           </PlanElements>
         </PlanElement>
         <PlanElement id="9" operation="HASH JOIN" access_predicates="&quot;T1&quot;.&quot;FATHER&quot;=NULL">
           <PlanElements>
             <PlanElement id="10" operation="CONNECT BY PUMP"/>
             <PlanElement id="11" operation="COUNT">
         <PlanElements>
           <PlanElement id="12" operation="HASH JOIN" option="RIGHT OUTER" cost="7" cardinality="1.230" bytes="33.210" cpu_cost="3.583.764" io_cost="6" access_predicates="&quot;T2&quot;.&quot;COUNTERPARTY&quot;(+)=&quot;T1&quot;.&quot;FATHER&quot;">
             <PlanElements>
               <PlanElement object_ID="0" id="13" operation="INDEX" option="FAST FULL SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="IDX_TS_BPU_EMAIL_FAMILY_CNT" object_type="INDEX" cost="3" cardinality="1.230" bytes="12.300" cpu_cost="176.086" io_cost="3"/>
               <PlanElement object_ID="1" id="14" operation="INDEX" option="FAST FULL SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="TS_BPU_EMAIL_FAMILY_PK" object_type="INDEX (UNIQUE)" cost="3" cardinality="1.230" bytes="20.910" cpu_cost="190.329" io_cost="3"/>
             </PlanElements>
           </PlanElement>
         </PlanElements>
             </PlanElement>
           </PlanElements>
         </PlanElement>
         <PlanElement id="15" operation="COUNT">
           <PlanElements>
             <PlanElement id="16" operation="HASH JOIN" option="RIGHT OUTER" cost="7" cardinality="1.230" bytes="33.210" cpu_cost="3.583.764" io_cost="6" access_predicates="&quot;T2&quot;.&quot;COUNTERPARTY&quot;(+)=&quot;T1&quot;.&quot;FATHER&quot;">
         <PlanElements>
           <PlanElement object_ID="0" id="17" operation="INDEX" option="FAST FULL SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="IDX_TS_BPU_EMAIL_FAMILY_CNT" object_type="INDEX" cost="3" cardinality="1.230" bytes="12.300" cpu_cost="176.086" io_cost="3"/>
           <PlanElement object_ID="1" id="18" operation="INDEX" option="FAST FULL SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="TS_BPU_EMAIL_FAMILY_PK" object_type="INDEX (UNIQUE)" cost="3" cardinality="1.230" bytes="20.910" cpu_cost="190.329" io_cost="3"/>
         </PlanElements>
             </PlanElement>
           </PlanElements>
         </PlanElement>
         <PlanElement object_ID="2" id="19" operation="INDEX" option="UNIQUE SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="TS_BPU_EMAIL_EXTRA_INFO_PK" object_type="INDEX (UNIQUE)" search_columns="1" cost="1" cardinality="1" bytes="10" cpu_cost="14.443" io_cost="1" access_predicates="&quot;COUNTERPARTY&quot;=:B1"/>
       </PlanElements>
           </PlanElement>
           <PlanElement id="20" operation="SORT" option="GROUP BY NOSORT" cost="4" cardinality="1" bytes="18" cpu_cost="29.741" io_cost="4">
       <PlanElements>
         <PlanElement object_ID="3" id="21" operation="TABLE ACCESS" option="BY INDEX ROWID" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="TS_SO_ENG_VALUATIONS_INFO" object_type="TABLE" object_instance="1" cost="4" cardinality="1" bytes="18" cpu_cost="29.741" io_cost="4" filter_predicates="&quot;V&quot;.&quot;CLIENT_CP_CODE&quot;=:B1">
           <PlanElements>
             <PlanElement object_ID="4" id="22" operation="INDEX" option="RANGE SCAN" optimizer="ANALYZED" object_owner="COMPANY_TREASURY" object_name="ENG_VAL_INFO_VAL_DATE_IDX" object_type="INDEX" search_columns="1" cost="3" cardinality="1" cpu_cost="21.564" io_cost="3" access_predicates="&quot;V&quot;.&quot;VAL_DATE&quot;=TO_DATE('2012-10-31 00:00:00', 'yyyy-mm-dd hh24:mi:ss')"/>
           </PlanElements>
         </PlanElement>
       </PlanElements>
           </PlanElement>
         </PlanElements>
       </PlanElement>
     </PlanElements>
   </PlanElement>
</ExplainPlan>

1 个答案:

答案 0 :(得分:1)

我在这里猜测你的树表结构(假设null parent表示根节点): -

CREATE TABLE TREE_TABLE (PARENT VARCHAR2(1), CHILD VARCHAR2(1));
CREATE TABLE TABLEXXX (CHILD_REF VARCHAR2(1) NOT NULL); 
insert into tree_table values (null, 'a');
insert into tree_table values ('a','b');
insert into tree_table values ('b', 'c');
insert into tree_table values (null, 'd');
insert into tree_table values (null, 'f');
insert into tree_table values ('f','g');
insert into tablexxx values ('c');
insert into tablexxx values ('f');
commit;

然后我们可以选择所有具有所选TABLEXXX值的节点作为这样的后代(您的输出表明您需要所有祖先节点而不仅仅是根节点): -

select child from tree_table 
connect by child = prior parent start with child in (select child_ref from tablexxx)

这给了我们: -

c
b
a
f

这表明我们是如何走树的。我们从你选择的节点(c和f)开始向上工作(所以级别是颠倒的): -

select sys_connect_by_path(child ||'(' || level || ')', '->'), child from tree_table 
connect by child = prior parent start with child in (select child_ref from tablexxx) 

->c(1)                c
->c(1)->b(2)          b
->c(1)->b(2)->a(3)    a
->f(1)                f