表myfirst3有4列和120万条记录。
表mtl_object_genealogy有超过1000万条记录。
运行以下代码需要很长时间。如何使用选项调整此代码?
WITH level1 as (
SELECT mln_parent.lot_number,
mln_parent.inventory_item_id,
gen.lot_num ,--fg_lot,
gen.segment1,
gen.rcv_date.
FROM mtl_lot_numbers mln_parent,
(SELECT MOG1.parent_object_id,
p.segment1,
p.lot_num,
p.rcv_date
FROM mtl_object_genealogy MOG1 ,
myfirst3 p
START WITH MOG1.object_id = p.gen_object_id
AND (MOG1.end_date_active IS NULL OR MOG1.end_date_active > SYSDATE)
CONNECT BY nocycle PRIOR MOG1.parent_object_id = MOG1.object_id
AND (MOG1.end_date_active IS NULL OR MOG1.end_date_active > SYSDATE)
UNION all
SELECT p1.gen_object_id,
p1.segment1,
p1.lot_num,
p1.rcv_date
FROM myfirst3 p1 ) gen
WHERE mln_parent.gen_object_id = gen.parent_object_id )
select /*+ NO_CPU_COSTING */ *
from level1;
执行计划
CREATE TABLE APPS.MYFIRST3
(
TO_ORGANIZATION_ID NUMBER,
LOT_NUM VARCHAR2(80 BYTE),
ITEM_ID NUMBER,
FROM_ORGANIZATION_ID NUMBER,
GEN_OBJECT_ID NUMBER,
SEGMENT1 VARCHAR2(40 BYTE),
RCV_DATE DATE
);
CREATE TABLE INV.MTL_OBJECT_GENEALOGY
(
OBJECT_ID NUMBER NOT NULL,
OBJECT_TYPE NUMBER NOT NULL,
PARENT_OBJECT_ID NUMBER NOT NULL,
START_DATE_ACTIVE DATE NOT NULL,
END_DATE_ACTIVE DATE,
GENEALOGY_ORIGIN NUMBER,
ORIGIN_TXN_ID NUMBER,
GENEALOGY_TYPE NUMBER,
);
CREATE INDEX INV.MTL_OBJECT_GENEALOGY_N1 ON INV.MTL_OBJECT_GENEALOGY(OBJECT_ID);
CREATE INDEX INV.MTL_OBJECT_GENEALOGY_N2 ON INV.MTL_OBJECT_GENEALOGY(PARENT_OBJECT_ID);
答案 0 :(得分:0)
你的解释计划显示了一些非常大的数字。优化器估计最终结果集大约为3227,000,000,000行。只返回那么多行需要一些时间。
所有表访问都是全表扫描。因为你有大桌子也会花时间。
至于改进,我们很难理解查询的逻辑。这是您的数据模型,业务规则和数据。你还没有解释任何事情,所以我们所能做的就是猜测。
为什么使用WITH子句?您只使用level
结果集一次,因此只需要一个常规的FROM子句。
你为什么要使用UNION ALL?该操作只会复制从myfirst3
检索到的记录(所有这些值都已包含在MOG1.object_id = p.gen_object_id
的行中。
MERGE JOIN CARTESIAN操作非常有趣。 Oracle使用它来实现传递闭包。这是一项昂贵的操作,但这是因为树木层次结构是一件昂贵的事情。不幸的是,您正在为具有2700万条记录的表生成所有父子关系。那很糟糕。
全表扫描不是问题所在。 myfirst3
上没有过滤器,所以显然数据库必须获取所有记录。如果每个myfirst3
记录都有一个父级,其中10%的内容为mtl_object_genealogy
,那么全表扫描效率会很高;但是你要整个层次结构卷起来,所以它就像你在看着更大的一块桌子。
面对这些数字,您的索引无关紧要。可能有帮助的是mtl_object_genealogy(OBJECT_ID, PARENT_OBJECT_ID, END_DATE_ACTIVE)
上的综合索引。
您希望myfirst3
中记录的所有级别的PARENT_OBJECT_ID。如果您经常运行此查询并且mtl_object_genealogy
是一个缓慢变化的表,您应该考虑将传递闭包实现到一个表中,该表只包含叶记录和父项的所有排列的记录。
总结一下: