我有一個PL/SQL腳本,循環人(~4百萬)的記錄和執行多個更新(〜100)和一個刪除語句(所有這些更新和刪除在不同的表)。我面臨的問題是,一個刪除語句本身佔用大約一半的運行時間。我明白,當你執行刪除語句時,它需要更新索引,但我覺得它很荒謬。我目前正在使用dbms_parallel_execute
使用一個線程測試此腳本,但我計劃對此腳本進行多線程處理。多個小刪除
我執行類似以下的查詢:
DELETE FROM table1 t1
WHERE (t1.key1, t1.key2) IN (SELECT t2.key1, t2.key2
FROM table2 t2
WHERE t2.parm1 = 1234
AND t2.parm2 = 5678).
以下事實:
- 表2(約30萬條記錄)是〜小於表1大10倍(約3萬條記錄) 。
- 有上表1主鍵(KEY1,KEY2)
- 有對錶2的主鍵(KEY1,KEY2)
- 有對錶2的索引(PARM1,parm2)
- 我已禁用在引用table2(key1,key2)的table1(key1,key2)上的外鍵約束
對table1沒有其他約束,但對table2有更多約束。
上table1的所有觸發器已被禁用
- 此查詢的解釋計劃來了一個成本比很多我的更新語句的較低(但我知道這並不佔太大)。
解釋計劃輸出:
OPERATION OPTIONS OBJECT_INSTANCE OBJECT_TYPE OPTIMIZER SEARCH_COLUMNS ID PARENT_ID DEPTH POSITION COST CARDINALITY BYTES CPU_COST IO_COST TIME
------------------------------------ ---------------------------------------------------------------------------------------------------- -------------------------------------------- ------------------------------------ ---------------------------------------------------------------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- --------------------------------------------
DELETE STATEMENT ALL_ROWS 0 0 5 5 1 36 38043 5 1
DELETE 1 0 1 1
NESTED LOOPS 2 1 2 1 5 1 36 38043 5 1
TABLE ACCESS BY INDEX ROWID 2 TABLE ANALYZED 3 2 3 1 4 1 25 29022 4 1
INDEX RANGE SCAN INDEX ANALYZED 1 4 3 4 1 3 1 21564 3 1
INDEX UNIQUE SCAN INDEX (UNIQUE) ANALYZED 2 5 2 3 2 1 1 11 9021 1 1
我在想,如果有什麼辦法讓這個刪除走得更快。我試圖做一個bulk delete
,但似乎並沒有改善運行時間。如果有任何方法可以執行所有的刪除操作,然後更新索引,我懷疑它會運行得更快。很顯然,從select中創建表格已經不在圖片之中,因爲我正在從另一個表中循環記錄(並通過多個條件運行)來執行刪除操作。
是你的表由任何機會索引組織?嘗試'從SELECT_TABLES SELECT IOT_TYPE WHERE TABLE_NAME ='MYTABLENAME''。如果結果不是NULL,則按索引組織。 –
兩個表上的結果都是NULL。 – Mocking
請保留解釋輸出的格式。縮進對分析它很重要。 –