[英]Oracle 11g - How to optimize slow parallel insert select?
我們想加快下面的並行插入語句的運行。 我們期望插入大約80M的記錄,大約需要2個小時才能完成。
INSERT /*+ PARALLEL(STAGING_EX,16) APPEND NOLOGGING */ INTO STAGING_EX (ID, TRAN_DT,
RECON_DT_START, RECON_DT_END, RECON_CONFIG_ID, RECON_PM_ID)
SELECT /*+PARALLEL(PM,16) */ SEQ_RESULT_ID.nextval, sysdate, sysdate, sysdate,
'8a038312403e859201405245eed00c42', T1.ID FROM PM T1 WHERE STATUS = 1 and not
exists(select 1 from RESULT where T1.ID = RECON_PM_ID and CREATE_DT >= sysdate - 60) and
UPLOAD_DT >= sysdate - 1 and (FUND_SRC_TYPE = :1)
我們認為緩存not exists列的結果會加快插入速度。 我們如何執行緩存? 有什么想法加快插入速度?
請參閱以下有關企業管理器的計划統計信息。 我們還注意到這些語句並不是並行運行的。 這是正常的嗎?
編輯:順便說一下,序列已經緩存到1M
改善統計數據 估計的行數是1,但實際行數超過700萬並且正在計數。 這會導致執行計划使用嵌套循環而不是散列連接。 嵌套循環可以更好地處理少量數據,並且散列連接可以更好地處理大量數據。 修復可能就像確保相關表格具有准確的當前統計數據一樣簡單。 這通常可以通過使用默認設置收集統計信息來完成,例如: exec dbms_stats.gather_table_stats('SIRS_UATC1', 'TBL_RECON_PM');
。
如果這不能改善基數估計,請嘗試使用動態采樣提示,例如/*+ dynamic_sampling(5) */
。 對於如此長時間運行的查詢,如果能夠獲得更好的計划,則需要花費額外的時間預先采樣數據。
使用語句級並行性而不是對象級並行性。 這可能是並行SQL最常見的錯誤。 如果使用對象級並行,則提示必須引用對象的別名 。 從11gR2開始,無需擔心指定對象。 此語句只需要一個提示: INSERT /*+ PARALLEL(16) APPEND */ ...
請注意, NOLOGGING
不是一個真正的提示。
嘗試使用更多綁定變量,尤其是在可能發生嵌套循環的情況下。 我注意到你可以在像這樣的情況下使用它
CREATE_DT >= :YOUR_DATE instead of CREATE_DT >= sysdate - 60
我認為這可以解釋為什么在執行計划的最低部分有1.8億次執行,即使更新查詢的其他部分仍然是7900萬中的800萬。
我可以看到兩大問題:
1 - 提示平行(在選擇中)NO NOT work,因為它應該像這樣+ PARALLEL(T1,16)
2 - SELECT不是最優的,如果避免表達式NOT IN會更好
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.