DELETE大批量数据的性能优化
http://litterbaby.itpub.net/post/16841/276327
?
DELETE大批量數據的性能優化
問題的提出:
一個表有上千萬的數據,欲從該表中刪除部分數據;
在線用的生產庫,不能影響生產;
該表有四個索引,刪除的sql語句用到了索引;
正常業務不能停止-不能disable約束,也不能臨時不用索引;
問題的解決:
這個問題中應該重點考慮的問題是這個系統是生產系統,不能離線,所以只能是根據情況考慮一些在線的刪除方式。
1、 如果是定期清楚歷史數據的話,可以考慮用partition的方式,采用分區方式是其優點之一,能夠使用其易于管理的一個方面,在這里是不是應該考慮分區時候是采用我們需要刪除的數據為分區的原則。
2、 增大回滾段,通過設置使用這個回滾段,來提高系統的刪除操作的速度,但是對于Oracle9i以后的系統來說,由于使用了自動管理回滾段的情況,如何進行回滾段的設置。
3、 增大redo log在線文件的大小,以便減少checkpoint的執行頻率,增大buffer來提高刪除的速度。這個主要目的是減少系統checkpoint的次數,盡量少減少磁盤IO的次數,能夠在數據緩存上執行的盡量在內存中實現。
4、 使用rowid來刪除數據。
1.根據用戶所提需求過濾需要刪除的源數據,create 臨時表 as select rowid rid from 需要刪除的表 where 刪除條件。
2.使用pl/sql block來刪除數據,這樣能保證及時遞交,防止lock過多的行導致系統負載增加。這里需要注意commit的頻率,一般為更新100條記錄commit一次。
| create table temp_del表名_040803 as select rowid rid from 要刪除的表 where ...... declare execrow number; begin execrow:=1; for i in 1..需要更新的記錄數/100(取整) loop delete 要刪除的表 where rowid in(select rid from temp_del表名_040803 where rownum<100); delete from temp_del表名_040803 where rownum<100; commit; end loop; end; / |
記得再建一張臨時表保存要刪除的內容已備回滾。這樣根據rowid來刪除的話效率會比較高。
5、 在Oracle 9i之后,可以考慮使用bulk delete的新功能。(這個沒有高清楚是什么東西)
6、 如果在不是生產庫的時候,如果索引沒有在刪除時使用的情況下,(如果在刪除的語句中使用了索引得話,這樣能夠提高刪除的速度)可以將索引刪除,等執行完刪除語句的時候,可以考慮重建索引,因為刪除索引上的數據的時候也是需要時間和系統消耗的,這時候需要看看你所要刪除的數據量的多少,如果數據量相對整個表比較大的時候,可以考慮使用全表掃描,這樣應該是更快的方式,如果比率比較小的時候,使用索引找到rowid來刪除應該是比較好的選擇。
7、 有人提出這樣的觀點:
| 相關問題,俺們也經常遇到,共享經驗如下: 1.表分區異常重要 2.索引過多很是麻煩 3.相關約束更是頭痛(4M數據如果有N個子表對其參照,乖乖..) 4.表空間如過是dictionary管理,必須選擇分段批量提交(俺們的數據庫都被鎖死了) 5.會滾、排序,大redo,多個arch線程,必須養成習慣,任何大數據量批量操作,都不可少。 6.臨時表(在臨時表空間上)用于查詢果然較快。 7.引用偶像的話“Delete就是慢,就是慢,就是慢.”,沒辦法。 最后還是想說,象這樣的工作只有考慮應用的特征,才會找到比較好的方法(俺覺得) |
問題:表空間如過是dictionary管理,必須選擇分段批量提交(俺們的數據庫都被鎖死了),為什么是這樣的?
?
==========================
http://www.oracle.com.cn/viewthread.php?tid=26214&extra=&page=1
?
======================
http://blog.csdn.net/lunar2000/archive/2005/06/27/404090.aspx
?
========================
總結
以上是生活随笔為你收集整理的DELETE大批量数据的性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel多条件求和 SUMPRODU
- 下一篇: 批量绑定(bulk binds):FOR