我有一個包含大約1.8億條記錄和40個索引的表。夜間程序將數據加載到此表中,但由於某些業務條件,我們只能刪除數據並將數據加載到此表中。每晚程序將從源系統中爲表中現有記錄帶來新記錄或更新。我們有限的窗口,即大約6小時完成源系統的提取,執行業務轉換並最終將數據加載到此目標表中,並且準備好讓用戶在早上使用這些數據。我們面臨的問題是,從表中刪除需要很長時間,主要是由於表中的40個索引(平均每小時刪除70000個)。我做了一些挖掘在互聯網上看到下面的選項在Oracle BIG表中刪除緩慢
一)丟棄或禁用索引中刪除之前,然後重新創建索引:它加載數據到目標表的程序刪除後並加載數據需要相當執行一些更新的索引是至關重要的。由於表中的大量數據,重建1個索引需要近1.5個小時。因此,這種方法是不可行的,由於它需要重建索引的時間和由於我們要準備好這些數據爲用戶
有限的時間B)使用批量刪除:目前該程序刪除基於ROWID並刪除記錄逐一如下
DELETE FROM <table> WHERE rowid = g_wpk_tab(ln_i);
g_wpk_tab是保存它是由通過FOR ALL循環讀取的rowid要刪除的收集和我做一箇中間媒介的提交每50000行刪除。
AskTom的湯姆說,在這個討論在這裏說,批量刪除和逐行刪除要用近的時間
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5033906925164
等量所以這不會是一個可行的選擇,以及
C)定期刪除:AskTom的湯姆建議使用定期刪除,甚至需要較長的時間可能是由於指數在這個表上的號碼
d)CTAS:這種方法是不成問題的,因爲該程序需要重新創建該表中,創建40個索引,然後與更新出發,我的索引如上所述將採取ATLEAST 1.5小時,以創建
如果你能提供任何其他建議,我會非常感激。
更新:截至目前,我們已決定採用https://stackoverflow.com/users/409172/jonearles建議的方法來存檔而不是刪除。方法是向表中添加一個標記,以將要刪除的記錄標記爲DELETE,然後在白天運行刪除程序以刪除記錄。這將確保數據在適當的時間爲用戶提供。由於用戶通過OBIEE使用,我們計劃在表上設置內容級過濾器,而不是查看存檔列,以便用戶不必知道要選擇什麼以及要忽略什麼。
對於使用「所有」,你的意思是你是批量收集rowids和使用'forall' ..?你有企業版嗎?你可以分區嗎?桌子是否需要如此之大?你有沒有考慮過讓它變小?你需要40個索引嗎?如果你刪除10,它會讓你的刪除速度更快。這聽起來好像你已經把整個數據庫放在一張表中......如果你有一個小的進程每天24小時刪除一些舊的記錄會有什麼不同? – Ben
你可以並行運行20個進程以加快刪除速度嗎?您可以使用DBMS_PARALLEL_EXECUTE來分割操作並輕鬆啓動20。你有沒有追溯到任何特定原因的緩慢;例如,如果整個表位於一個磁盤上,並且您有20-30個進程試圖從同一磁盤上刪除,則可能會遇到大量I/O問題。如果你有多個進程試圖從相同的塊中刪除rowid,你會得到爭用。最後,你在用什麼磁盤?它們是15年前的5rpm旋轉磁盤還是他們可愛的新型9k/TB SAN? – Ben
我正在使用所有循環通過具有rowid的集合。我沒有使用批量收集。我被告知,分區成本很高,客戶無法負擔得起。該表包含公司過去4個會計年度的詳細級別的發票交易。我們正在考慮是否可以刪除一些索引。我已經開始嘗試刪除一些索引並查看性能增益。 – Shaz