進來做性能調優,測試兩個表(一個百萬級、一個千萬級)的批量插入速度,免不了要刪掉所有記錄后重來。眾所周知,TRUNCATE TABLE要比DELETE FROM迅速很多,所以一直是用TRUNCATE TABLE。
但折騰過幾回后,發現有關這兩個表的SELECT、DELETE、UPDATE語句變得巨慢。查看這些SQL的執行計划,也都跟預想一樣利用了索引。但無論如何調整,就一直很慢。
后來某天突來靈感,會不會是索引本身有了問題?於是rebuild了索引,為保險起見再重做表分析,結果立即見效,所有sql恢復了以前的運行速度。
個人猜測,因為TRUNCATE TABLE是直接釋放數據頁,很有可能會引起索引數據的不一致或紊亂;表越大、TRUNCATE次數越多,影響程度越嚴重。
再進一步測試,得到如下的經驗:
- 在本人的測試環境(Oracle 12c, 64G PGA)中,經過三四次TRUNCATE就須重建索引;
- 重建索引的合適時機是批量插入完成后,而剛TRUNCATE完成就重建索引,貌似毫無效果;
- 重做表分析也能帶來一些性能提升,但不如重建索引直接見效。