2012-11-23 76 views
0

有沒有什麼辦法來優化遞歸查詢?SQL。遞歸查詢。我如何優化此查詢?

表:

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> 
+0

您可以發佈查詢的解釋計劃嗎? –

+1

查詢中左側自動加入的用途是什麼?這似乎沒有任何用途,因爲你已經在做一個連接了。 –

+0

這是獲得我樹的分支的方式。 Connect By通過定義退出遞歸的條件 –

回答

1

我猜一點點在你的樹表結構,這裏(假設null父意味着根節點): -

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 
+0

Thnaks彼得勳爵,我會在星期一嘗試 –

+0

40秒到250毫秒。多謝彼得主 –