[英]WITH Clause performance issue in Oracle 11g
表 myfirst3 有 4 列和 120 萬條記錄。
表 mtl_object_genealogy 有超過 1000 萬條記錄。
運行下面的代碼需要很長時間。 如何使用 with 選項調整此代碼?
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);
你的解釋計划顯示了一些非常大的數字。 優化器估計最終結果集將約為 3227,000,000,000 行。 僅僅返回那么多行需要一些時間。
所有表訪問都是全表掃描。 因為你有大桌子,也會吃時間。
至於改進,我們很難理解您的查詢邏輯。 這是您的數據模型、您的業務規則、您的數據。 你沒有解釋任何事情,所以我們只能猜測。
為什么要使用 WITH 子句? 您只使用一次level
結果集,因此只需使用常規的 FROM 子句即可。
為什么要使用 UNION ALL? 該操作只是復制從myfirst3
檢索到的記錄(所有這些值都已包含在MOG1.object_id = p.gen_object_id
行中。
MERGE JOIN CARTESIAN 操作很有趣。 Oracle 使用它來實現傳遞閉包。 這是一個昂貴的操作,但那是因為樹遍歷層次結構是一件昂貴的事情。 不幸的是,您正在為具有 2700 萬條記錄的表生成所有父子關系。 那很糟。
全表掃描不是問題。 myfirst3
上沒有過濾器,因此顯然數據庫必須獲取所有記錄。 如果每個myfirst3
記錄有一個父項,它是內容mtl_object_genealogy
的 10%,那么全表掃描將是有效的; 但是您正在卷起整個層次結構,因此就像您正在查看表格的更大部分一樣。
面對這些數字,您的索引無關緊要。 可能有幫助的是mtl_object_genealogy(OBJECT_ID, PARENT_OBJECT_ID, END_DATE_ACTIVE)
上的復合索引。
您需要myfirst3
記錄的所有級別的 PARENT_OBJECT_ID 。 如果你經常運行這個查詢並且mtl_object_genealogy
是一個緩慢變化的表,你應該考慮將傳遞閉包物化到一個表中,該表只包含葉記錄和父項的所有排列的記錄。
總結:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.