一、大佬說(楊廷琨)
LOCAL索引的最大好處是在進行分區操作,比如TRUNCATE PARTITION, DROP PARTITION時,不會出現索引INVALID的情況,不影響索引的可用性。由于GLOBAL索引所有的數據存儲在一起,因此當執行分區操作的時候,索引會失效,而如果想要保證所有的有效性,需要增加UPDATE (GLOBAL) INDEXES語句,這使得原本很快結束的DDL操作,由于需要維護全局索引而變得非常緩慢,且產生大量的日志。12c之后,全局索引的異步同步可以緩解全局索引的這個問題。
而GLOBAL索引的好處是,在表變為分區后,只要索引仍然是GLOBAL索引,通過索引訪問數據的效率就不會下降。由于LOCAL索引的索引分區數量和表分區數量相等,如果訪問一個LOCAL索引,且查詢條件未指定分區鍵值,這時Oracle將會掃描所有的索引分區。而GLOBAL索引則只需要訪問一棵索引樹,當分區數量眾多時,二者的效率差異是非常明顯的。
當然,它們還有其他的區別。就用戶而言,判斷需要GLOBAL還是LOCAL索引,最主要看是否會頻繁進行分區的維護操作,比如定期刪除老分區,如果是的話,LOCAL是最佳選擇,如果不是,則考慮GLOBAL索引。
二、索引驗證
1、創建臨時表
CREATE TABLE TEST1 (hid?number,hid2?number,hchar1 char(50))?
PARTITION BY?RANGE(hid)?INTERVAL (10)
( PARTITION p01 VALUES LESS THAN (5));
2、創建主鍵不加USING INDEX LOCAL默認是全局索引
ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST PRIMARY KEY (hid) ?--全局索引;
ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST PRIMARY KEY (hid) USING INDEX?LOCAL;
3、主鍵是非分區字段
ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST PRIMARY KEY (hid2) ?--正常執行;
ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST PRIMARY KEY (hid2) USING INDEX?LOCAL?--報錯ORA-14039: 分區列必須構成 UNIQUE 索引的關鍵字列子集;
ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST PRIMARY KEY (hid2,hid) USING INDEX?LOCAL??--正常執行;
3、unique索引是非分區字段
create?unique?index pk_ID on TEST1(HID2)?local--報錯ORA-14039: 分區列必須構成 UNIQUE 索引的關鍵字列子集;
create?unique?index pk_ID on TEST1(HID2,HID)?local?--正常執行;
create?unique?index pk_ID on TEST1(HID2) --正常執行;
alter table TEST1 add constraint pk_ID2 primary key(HID2) using index pk_ID --正常執行;
create index pk_ID99 on TEST1(HID2)?local?--正常執行;
alter table TEST1 add constraint pk_ID99_2 primary key(HID2) using index pk_ID99 ?--報錯ORA-14196: 指定的索引不能用于強制約束條件;
4、非分區字段創建主鍵,則創建主鍵local索引時必須加上分區字段
ALTER TABLE TEST ADD CONSTRAINT PK_TEST PRIMARY KEY (主鍵字段,分區字段) USING INDEX LOCAL;
主鍵做local索引必須包含分區鍵的字段。這和oracle 如何保證紀錄唯一有關,如果unique index key沒有partition_key,那么每插入一行的紀錄,只保證它所進入的分區中是唯一的,不保證在整個表上這個記錄是否唯一,這就違背了主鍵的意義。(如果和分區字段一起綁定,則不需要掃描所有的索引分區就能驗證整個表上這個記錄是否唯一)。
5、range分區
range分區,單個分區內非分區字段的值不是順序的,分區字段值也不是順序的(如按100值分區,第一個分區是1-100,順序可能是7,1,3,67,9這樣的,第二分區101-200,順序可能是199,136,103,178這樣的,但是相對兩個分區而言,第二個分區和第一個分區值的范圍是順序的)
分區字段的分區索引是順序的,因為第一個數據分區開始到后面的數據分區是range順序的,雖然單獨的數據分區內數據不是順序的
非分區字段只是某一分區索引內的索引是順序的,不代表分區索引是順序的。