ORACLE重建索引詳解
一、重建索引的前提
1、表上頻繁發生update,delete操作;
2、表上發生了alter table ..move操作(move操作導致了rowid變化)。
二、重建索引的標準
1、索引重建是否有必要,一般看索引是否傾斜的嚴重,是否浪費了空間, 那應該如何才可以判斷索引是否傾斜的嚴重,是否浪費了空間, 對索引進行結構分析(如下):
SQL>Analyze index index_name validate structure;
2、在執行步驟1的session中查詢index_stats表,不要到別的session去查詢。
SQL>select height,DEL_LF_ROWS/LF_ROWS from index_stats;
說明:當 查詢出來的 height>=4 或者 DEL_LF_ROWS/LF_ROWS>0.2 的場合 , 該索引考慮重建 。
舉例: (t_gl_assistbalance 26 萬多條資訊 )
SQL> select count(*) from t_gl_assistbalance ;
輸出結果:
COUNT(*)
----------
265788
SQL> Analyze index IX_GL_ASSTBAL_1 validate structure;
Index analyzed
SQL> select height,DEL_LF_ROWS/LF_ROWS from index_stats;
輸出結果:
HEIGHT DEL_LF_ROWS/LF_ROWS
---------- -------------------
4 1
三、重建索引的方式
1、drop 原來的索引,然後再建立索引;
舉例:
刪除索引:drop index IX_PM_USERGROUP;
建立索引:create index IX_PM_USERGROUP on T_PM_USER (fgroupid);
說明:此方式耗時間,無法在24*7環境中實現,不建議使用。
倫理片http://www.dotdy.com/
2 、直接重建:
舉例:
alter index indexname rebuild; 或alter index indexname rebuild online;
說明:此方式比較快,可以在24*7環境中實現,建議使用此方式。
四、alter index rebuild 內部過程和注意點
alter index rebuild 和alter index rebuil online的區別
1、掃描方式不同
1.1、Rebuild以index fast full scan(or table full scan) 方式讀取原索引中的資料來構建一個新的索引,有排序的操作;
1.2、rebuild online 執行表掃描獲取資料,有排序的操作;
說明:Rebuild 方式 (index fast full scan or table full scan 取決於統計資訊的cost)
舉例1
SQL> explain plan for alter index IX_GL_ASSTBAL_1 rebuild;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
---------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | 999K| 4882K| 3219 |
| 1 | INDEX BUILD NON UNIQUE| IDX_POLICY_ID2 | | | |
| 2 | SORT CREATE INDEX | | 999K| 4882K| |
| 3 | INDEX FAST FULL SCAN | IDX_POLICY_ID2 | 999K| 4882K| |
---------------------------------------------------------------------
舉例2
SQL> explain plan for alter index idx_policy_id rebuild;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
---------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | 2072K| 9M| 461 |
| 1 | INDEX BUILD NON UNIQUE| IDX_POLICY_ID | | | |
| 2 | SORT CREATE INDEX | | 2072K| 9M| |
| 3 | TABLE ACCESS FULL | TEST_INDEX | 2072K| 9M| 461 |
舉例3 ( 注意和 舉例1 比較 )
Rebuil online 方式 :
SQL> explain plan for alter index idx_policy_id2 rebuild online;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
---------------------------------------------------------------------| 0 | ALTER INDEX STATEMENT | | 999K| 4882K| 3219 |
| 1 | INDEX BUILD NON UNIQUE| IDX_POLICY_ID2 | | | |
| 2 | SORT CREATE INDEX | | 999K| 4882K| |
| 3 | TABLE ACCESS FULL | TEST_INDEX2 | 999K| 4882K| 3219 |
2 、rebuild 會阻塞 dml 操作 ,rebuild online 不會阻塞 dml 操作 ;
3 、rebuild online 時系統會產生一個 SYS_JOURNAL_xxx 的 IOT 型別的系統臨時日誌表 , 所有 rebuild online 時索引的變化都記錄在這個表中 , 當新的索引建立完成後 , 把這個表的記錄維護到新的索引中去 , 然後 drop 掉舊的索引 ,rebuild online 就完成了。
注意點:
1、 執行rebuild操作時,需要檢查表空間是否足夠;
2、雖然說rebuild online操作允許dml操作,但是還是建議在業務不繁忙時間段進行;
Rebuild操作會產生大量redo log ;
五、重建分割槽表上的分割槽索引
重建分割槽索引方法:
Alter index indexname rebuild partition paritionname tablespace tablespacename;
Alter index indexname rebuild subpartition partitioname tablespace tablespacename;
Partition name 可以從user_ind_partitions查詢
Tablepace 引數允許alter index操作更改索引的儲存空間;
六、索引狀態描述
在資料字典中檢視索引狀態,發現有三種:
valid:當前索引有效
N/A :分割槽索引 有效
unusable:索引失效
七、術語
1、高基數:簡單理解就是表中列的不同值多。
2、低基數:建單理解就是表中的列的不同值少。
3、以刪除的葉節點數量:指得是資料行的delete操作從邏輯上刪除的索引節點 的數量,要記住oracle在刪除資料行後,將 “ 死 “ 節點保留在索引中,這樣做可以加快sql刪除操作的速度,因此oracle刪除資料行後可以不必重新平衡索引。
4、索引高度:索引高度是指由於資料行的插入操作而產生的索引層數,當表中新增大量資料時,oracle將生成索引的新層次以適應加入的資料行,因此,oracle索引可能有4層,但是這隻會出現在索引數中產生大量插入操作的區域。Oracle索引的三層結構可以支援數百萬的專案,而具備4層或是更多層的需要重建。
5、每次索引訪問的讀取數:是指利用索引讀取一資料行時所需要的邏輯I/O運算元,邏輯讀取不必是物理讀取,因為索引的許多內容已經儲存在資料緩衝區,然而,任何資料大於10的索引都需要重建。
6、什麼時候重建呢?
察看 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 ’
就能看到是否這個索引被刪除的百分比。
7、什麼樣的重建方式更好?
(1)建索引的辦法:
1.1、刪除並從頭開始建立索引。
1.2 、 使用 alter index index_name rebuild 命令重建索引。
1.3 、 使用 alter index index_name coalesce 命令重建索引。
(2)、下面討論一下這三種方法的優缺點:
2.1、刪除並從頭開始建索引:方法是最慢的,最耗時的。一般不建議。
2.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字句,以保證重建工作是在現有索引相同的表空間進行。
2.3、alter index index_name coalesce
使用帶有coalesce引數時重建期間不需要額外空間,它只是在重建索引時將處於同一個索引分支內的葉塊拼合起來,這最大限度的減少了與查詢過程中相關的潛在的加鎖問題,但是,coalesce選項不能用來將一個索引轉移到其他表空間。
八、其他
1、truncate 分割槽操作和truncate 普通表的區別?
1.1、Truncate 分割槽操作會導致全域性索引失效; truncate 普通表對索引沒有影響;
1.2、Truncate 分割槽操作不會釋放全域性索引中的空間,而truncate 普通表會釋放索引所佔空間;
2、rename 表名操作對索引沒有影響,因為rename操作只是更改了資料字典,表中資料行的rowid並沒有發生變化
總結:
1、判斷是否需要重建索引:
SQL>analyze index index_name validate structure;
SQL> select height,DEL_LF_ROWS/LF_ROWS from index_stats;
( 或 Select index_name,blevel from dba_indexes where blevel>=4 );
說明 : 當查詢出來的 height>=4 或者 DEL_LF_ROWS/LF_ROWS>0.2 的場合 , 該索引考慮重建 ;
2 、重建索引方法 :
方法一、
Alter index index_name rebuild tablespace tablespace_name;
優點:是快速重建索引的一種有效的辦法,可以用來將一個索引移到新的表空間。
缺點:重建期間需要額外空間。
方法二、
alter index index_name coalesce;
優點:重建期間不需要額外空間。
缺點:coalesce選項不能用來將一個索引轉移到其他表空間。