正常來說,資料都會區分"熱資料"&"冷資料",並存放在不同的地方,藉此來保持資料庫效能穩定與儲存空間成本。而在將熱資料搬到冷資料這件事,通常會實作清除或 Archival 的動作。
但有時候會遇到,資料的清理一直都有正常在跑,卻發現有些查詢居然就變成了 long query。這時候可能就是中了沒有 rebuild index 的問題。
在 Oracle 的 B-tree Index 結構中,當你執行 DELETE 的時候,其實 Index 中的相對應節點並不會從結構中被移除,只是會被標記為「邏輯刪除」。
所以當你的查詢是類似「區間」的查詢條件,例:<= 或 >= 這種。Oracle 就還是要掃描這些已經被標記為刪除的「幽靈節點」(即使這些資料已經從 Data Table 中移除了)。
所以你砍的資料越多(並且都沒有 rebuild index),range scan 這些沒用的「幽靈節點」就越多,變成是100% 的工作,可能有 90% 以上都在讀取這些沒用的 block。
就是 Rebuild index。Oracle 會重新整理 Index 的節點資料,將那些所謂的「幽靈節點」全部都刪掉。
假如你 rebuild index 的時機幾乎都不會是在 downtime 時候,一定要記得加上 rebuild online 的關鍵字。不然有很大的機率就直接 downtime 了,尤其是當你 build 的那個表是個大表時……。
這種區間查詢變慢的問題不會馬上浮現,它是會慢慢的變慢,直到有一天被 user report 或是 alert 出來的時候才會發現。
而更慘的情況是,那個 index 的設計不會用區間來查詢,而是較精準的特定欄位欄位查詢。
這種查詢它不會變慢,可是在硬碟空間的使用上卻會越佔越多。而一般「熱資料」機器上的儲存狀置性能又都比較好,如果都被這些所謂的「幽靈節點」給佔著,基本上是一種較不健康的狀態。