2017-05-27 73 views
2

希望優化需要更長時間才能完成的重要語句。優化插入帶減號的查詢

基本上過程中會:

1)由5點的插入,一個接一個地插入上NG_ORGANIZATION_CATEGORY_GTMP數據。這些DML使用每個查詢需要10秒鐘。從最後一絲,這些DML的插入的行數如下:

Insert 1 - 292770 
Insert 2 - 106648 
Insert 3 - 67358 
Insert 4 - 47775 
Insert 5 - 6147 

2)有問題的查詢來看,將只對表NG_ORGANIZATION_CATEGORY約6行(此表有大約414K行)。

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE) 
    SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE 
    FROM NG_ORGANIZATION_CATEGORY_GTMP 
    WHERE (ORGANIZATION_ID,CATEGORY_CODE) IN (
      SELECT ORGANIZATION_ID,CATEGORY_CODE 
      FROM NG_ORGANIZATION_CATEGORY_GTMP 
      MINUS 
      SELECT ORGANIZATION_ID,CATEGORY_CODE 
      FROM NG_ORGANIZATION_CATEGORY); 

3)方法從NG_ORGANIZATION_CATEGORY表刪除數據。這也很好。

DELETE FROM NG_ORGANIZATION_CATEGORY 
WHERE 
(ORGANIZATION_ID,CATEGORY_CODE) IN (SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY MINUS SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY_GTMP); 

下面是有問題的插入跟蹤:

SQL ID: gwxs083gcfdd2 Plan Hash: 2436575860 

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE) 
    SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE FROM 
    NG_ORGANIZATION_CATEGORY_GTMP WHERE (ORGANIZATION_ID,CATEGORY_CODE) IN (
    SELECT ORGANIZATION_ID,CATEGORY_CODE FROM NG_ORGANIZATION_CATEGORY_GTMP 
    MINUS SELECT ORGANIZATION_ID,CATEGORY_CODE FROM NG_ORGANIZATION_CATEGORY) 



call  count  cpu elapsed  disk  query current  rows 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
Parse  1  0.00  0.00   0   0   0   0 
Execute  1 6704.07 6705.98   2 424814954   25   6 
Fetch  0  0.00  0.00   0   0   0   0 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
total  2 6704.07 6705.98   2 424814954   25   6 

Misses in library cache during parse: 1 
Misses in library cache during execute: 1 
Optimizer mode: ALL_ROWS 
Parsing user id: 146  (recursive depth: 1) 
Number of plan statistics captured: 1 

Rows (1st) Rows (avg) Rows (max) Row Source Operation 
---------- ---------- ---------- --------------------------------------------------- 
     0   0   0 LOAD TABLE CONVENTIONAL (cr=424814954 pr=2 pw=0 time=923492126 us) 
     6   6   6 FILTER (cr=424814953 pr=0 pw=0 time=1667461141 us) 
    414050  414050  414050 TABLE ACCESS FULL NG_ORGANIZATION_CATEGORY_GTMP (cr=1023 pr=0 pw=0 time=121231 us cost=2 size=35 card=1) 
     6   6   6 MINUS (cr=424813930 pr=0 pw=0 time=2409881660 us) 
    414050  414050  414050  SORT UNIQUE NOSORT (cr=423573150 pr=0 pw=0 time=2406932080 us cost=3 size=35 card=1) 
    414050  414050  414050  TABLE ACCESS FULL NG_ORGANIZATION_CATEGORY_GTMP (cr=423573150 pr=0 pw=0 time=2406112290 us cost=2 size=35 card=1) 
    414044  414044  414044  INDEX UNIQUE SCAN NG_ORG_CATEGORY_PK (cr=1240780 pr=0 pw=0 time=2134347 us cost=2 size=11 card=1)(object id 108100) 


Elapsed times include waiting on following events: 
    Event waited on        Times Max. Wait Total Waited 
    ---------------------------------------- Waited ---------- ------------ 
    gc cr grant 2-way        1  0.00   0.00 
    db file sequential read       2  0.13   0.13 
    gc current grant 2-way       6  0.00   0.00 
******************************************************************************** 

能否請你幫我,讓我知道我可以調整這個查詢?我在考慮添加一個並行提示,但由於查詢中的MINUS,它將被忽略。

請讓我知道你是否有任何想法,如果你需要任何其他信息。

感謝您的關注。

由於提前,

威爾

回答

0

你可以使用內部聯接,而不是在那裏()的

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE) 
SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 
FROM NG_ORGANIZATION_CATEGORY_GTMP 
INNER JOIN (
    SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY_GTMP 
    MINUS 
    SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY 
) T1 on NG_ORGANIZATION_CATEGORY_GTMP.ORGANIZATION_ID = T1.ORGANIZATION_ID 
      and NG_ORGANIZATION_CATEGORY_GTMP.CATEGORY_CODE = T1.CATEGORY_CODE 

和一個簡單的提示刪除該別名形式的選擇(是不是有用)

+0

非常感謝..我會試試這個! – Will

+0

嗨@scaisEdge ...我工作並在不到1秒內跑完了!我只需要確認數據,但是在插入之前我運行了一個MINUS計數,並且插入了相同數量的數據。我將在週一與開發人員覈對並回到這篇文章!就目前而言,謝謝你,你是男人! – Will

+0

以及如果我的答案是正確的,請將其標記爲已接受...看到這裏如何 http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – scaisEdge

0

根據您的查詢,只有當數據不存在於類別表中時才需要將數據插入到gtmp表中。 你可以試試下面的查詢:

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE) 
    SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE FROM 
    NG_ORGANIZATION_CATEGORY_GTMP T1 WHERE NOT EXISTS (
SELECT 1 FROM NG_ORGANIZATION_CATEGORY T2 WHERE T1.ORGANIZATION_ID=T2.ORGANIZATION_ID AND T1.CATEGORY_CODE=T2.CATEGORY_CODE); 
0

您可以使用MERGE語句填充目標表,只有從源頭上表中不存在行:

merge into ng_organization_category noc 
using (select distinct organization_id, 
       category_code 
     from ng_organization_category_gtmp) gtmp 
    on (gtmp.organization_id = noc.organization_id 
     and gtmp.category_code = noc.category_code) 
when not matched then 
    insert (organization_id, category_code, added_date) 
    values (gtmp.organization_id, gtmp.category_code, :B1) 
/

的不同之處在USING子查詢可能不是必需的,它取決於您的源數據。 (您現有的INSERT語句會插入多個的實例,如果GTMP表具有它們,所以可能沒關係。)

+0

嗨@APC ..感謝您的幫助!我將等待DEV驗證scaisEdge提供的建議,如果它沒有用處。我會嘗試您的指示!非常感謝您的幫助。 – Will