一、前言
Oracle建議對於索引深度超過4級以及已刪除的索引條目至少占有現有索引條目總數的20% 這2種情形下需要重建索引。有人持不同觀點,就是強烈建議不要定期重建索引。索引重建是一個爭論不休被不斷熱烈討論的議題。
1、重建索引的理由
a、Oracle的B樹索引隨著時間的推移變得不平衡(誤解)
b、索引碎片在不斷增加
c、索引不斷增加,刪除的空間沒有重復使用
d、索引 clustering factor (集群因子)不同步,可以通過重建修復(誤解)
2、反對重建索引的理由
a、大多數腳本都依賴 index_stats 動態表。此表使用以下命令填充:
analyze index ... validate structure;
盡管這是一種有效的索引檢查方法,但是它在分析索引時會獲取獨占表鎖。對於大型索引,其影響會是巨大的,因為在此期間不允許對表執行DML 操作。
雖然該方法可以在不鎖表的情況下在線運行,但是可能要消耗額外的時間。
b、重建索引的直接結果是 REDO 活動可能會增加,總體系統負載也可能會提高。
插入/更新/刪除操作會導致索引隨著索引的分割和增長不斷發展。
重建索引後,它將連接的更為緊湊;但是,隨著對表不斷執行 DML 操作,必須再次分割索引,直到索引達到平衡為止。
結果,重做活動增加,且索引分割更有可能對性能產生直接影響,因為我們需要將更多的 I/O、CPU 等用於索引重建。
經過一段時間後,索引可能會再次遇到"問題",因此可能會再被標記為重建,從而陷入惡性循環。
因此,通常最好是讓索引處於自然平衡和(或)至少要防止定期重建索引。
3、Oracle的最終建議
一般而言,極少需要重建 B 樹索引,基本原因是 B 樹索引很大程度上可以自我管理或自我平衡。
大多數索引都能保持平衡和完整,因為空閒的葉條目可以重復使用。
插入/更新和刪除操作確實會導致索引塊周圍的可用空間形成碎片,但是一般來說這些碎片都會被正確的重用。
Clustering factor群集因子反映了給定的索引鍵值所對應的表中的數據排序情況。重建索引不會對群集因子產生影響,集群因子只能通過重組表的數據改變。
強烈建議不要定期重建索引,而應使用合適的診斷工具。
個人結論,如果重建索引的巨大工作量與之對應的是極小的收益,那就得不償失。如果系統有可用空閒期,重建之前和之後的測量結果表明性能有提高,值得重建。
4、改良方法
通常是優先考慮index coalesce(索引合並),而不是重建索引。索引合並有如下優點:
a、不需要占用近磁盤存儲空間 2 倍的空間
b、可以在線操作
c、無需重建索引結構,而是盡快地合並索引葉塊,這樣可避免系統開銷過大。
5、真正需要重建索引的情形
索引或索引分區因介質故障損壞
標記為UNUSABEL的索引需要重建
索引移動到新的表空間或需要改變某些存儲參數
通過SQL*Loader加載數據到表分區後,需要重建索引分區
重建索引以啟用鍵壓縮
位圖索引本質不同於B樹索引,建議重建
二、術語
1、高基數:簡單理解就是表中列的不同值多。
2、低基數:建單理解就是表中的列的不同值少。
3、以刪除的葉節點數量:指得是數據行的delete操作從邏輯上刪除的索引節點 的數量,要記住oracle在刪除數據行後,將 " 死 " 節點保留在索引中,這樣做可以加快sql刪除操作的速度,因此oracle刪除數據行後可以不必重新平衡索引。
4、索引高度:索引高度是指由於數據行的插入操作而產生的索引層數,當表中添加大量數據時,oracle將生成索引的新層次以適應加入的數據行,因此,oracle索引可能有4層,但是這只會出現在索引數中產生大量插入操作的區域。Oracle索引的三層結構可以支持數百萬的項目,而具備4層或是更多層的需要重建。
5、每次索引訪問的讀取數:是指利用索引讀取一數據行時所需要的邏輯I/O操作數,邏輯讀取不必是物理讀取,因為索引的許多內容已經保存在數據緩沖區,然而,任何數據大於10的索引都需要重建。
三、什麼時候重建呢?
察看 dba_indexes 中的 blevel 。這列是說明索引從根塊到葉快的級別,或是深度。如果級別大於等於4。則需要重建,
如下 :Select index_name,blevel from dba_indexes where blevel>=4.
另一個從重建中受益的指標顯然是當該索引中的被刪除項占總的項數的百分比。如果在20%以上時,也應當重建,如下
SQL>analyze index index_name validate structure
SQL>select (del_lf_rows_len/lf_rows_len)*100 from index_stats where name=' index_name '
就能看到是否這個索引被刪除的百分比。
四、重建索引的方法
1、刪除並從頭開始建索引:方法是最慢的,最耗時的。一般不建議。
2、使用 alter index index_name rebuild 命令重建索引。
3、alter index indexname rebuild online;
4、使用 alter index index_name coalesce 命令重建索引。
五、什麼樣的重建方式更好?
1、刪除並從頭開始建索引:方法是最慢的,最耗時的。一般不建議。
2、Alter index index_name rebuild
快速重建索引的一種有效的辦法,因為使用現有索引項來重建新索引,如果客戶操作時有其他用戶在對這個表操作,盡量使用帶online參數來最大限度的減少索引重建時將會出現的任何加鎖問題,alter index index_name rebuild online。
但是,由於新舊索引在建立時同時存在,因此,使用這種技巧則需要有額外的磁盤空間可臨時使用,當索引建完後把老索引刪除,如果沒有成功,也不會影響原來的索引。利用這種辦法可以用來將一個索引移到新的表空間。
Alter index index_name rebuild tablespace tablespace_name 。
這個命令的執行步驟如下:
首先,逐一讀取現有索引,以獲取索引的關鍵字。
其次,按新的結構填寫臨時數據段。
最後,一旦操作成功,刪除原有索引樹,將臨時數據段重命名為新的索引。
需要注意的是alter index index_name rebuild 命令中必須使用tablespace字句,以保證重建工作是在現有索引相同的表空間進行。
3、alter index index_name coalesce
使用帶有coalesce參數時重建期間不需要額外空間,它只是在重建索引時將處於同一個索引分支內的葉塊拼合起來,這最大限度的減少了與查詢過程中相關的潛在的加鎖問題,但是,coalesce選項不能用來將一個索引轉移到其他表空間。
六、重建分區表上的分區索引
重建分區索引方法:
Alter index indexname rebuild partition paritionname tablespace tablespacename;
Alter index indexname rebuild subpartition partitioname tablespace tablespacename;
Partition name 可以從user_ind_partitions查找
Tablepace 參數允許alter index操作更改索引的存儲空間。