有没有办法优化递归查询?
表:
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 "TS_SO_ENG_VALUATIONS_INFO" "V" WHERE "V"."VAL_DATE"=TO_DATE('2012-10-31 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND "V"."CLIENT_CP_CODE"=:B1 GROUP BY "CLIENT_CP_CODE")">
<PlanElements>
<PlanElement id="2" operation="CONNECT BY" option="WITH FILTERING" filter_predicates=" EXISTS (SELECT 0 FROM "TS_BPU_EMAIL_EXTRA_INFO" "TS_BPU_EMAIL_EXTRA_INFO" WHERE "COUNTERPARTY"=:B1)">
<PlanElements>
<PlanElement id="3" operation="FILTER" filter_predicates=" EXISTS (SELECT 0 FROM "TS_BPU_EMAIL_EXTRA_INFO" "TS_BPU_EMAIL_EXTRA_INFO" WHERE "COUNTERPARTY"=: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=""T2"."COUNTERPARTY"(+)="T1"."FATHER"">
<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=""COUNTERPARTY"=:B1"/>
</PlanElements>
</PlanElement>
<PlanElement id="9" operation="HASH JOIN" access_predicates=""T1"."FATHER"=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=""T2"."COUNTERPARTY"(+)="T1"."FATHER"">
<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=""T2"."COUNTERPARTY"(+)="T1"."FATHER"">
<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=""COUNTERPARTY"=: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=""V"."CLIENT_CP_CODE"=: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=""V"."VAL_DATE"=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)
我在这里猜测你的树表结构(假设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