淺談索引系列之本地索引與全局索引
分區表按照類型可以分為范圍分區(Range)、列表分區(List)以及哈希分區(Hash),表被分區后,其對應的索引也會與普通表的索引有所不同。
基本概念
對于分區表上的索引可以分為兩類:本地索引和全局索引。其中全局索引又可以分為分區索引和未分區索引,而本地索引必須為分區索引。因此若某個索引未分區,可以直接斷定其為全局索引;若已分區,在根據具體情況進行判斷。官方截圖如下:
本文重點說明Local Partitioned Index(為配合上圖此處才這么寫,可以簡寫為Local Index,因為Local Index一定是分區的)和Global Partitioned Index的基本概念原理以及其對應使用的場景。
本地索引的分區機制與表的分區機制一樣:其分區鍵與分區表的分區鍵相同,同樣分區個數與基表分區個數也相同,因此本地索引分區情況與基表一模一樣。
全局分區索引分區鍵以及分區個數與基表可能不同,另外全局分區索引必須為前綴索引,即其索引分區鍵必須為索引的前幾列。
用文字描述比較枯燥,難于理解,下圖比較形象的說明了兩者以及兩者的區別。
Local Index global Partition Index
應用場景
那么本地索引和全局分區索引或全局索引究竟適用于什么場景呢?,下面以本地索引和全局索引(非分區)為例進行說明:
1. 新建測試以ID為分區鍵的范圍分區表T_PARTITION,具體表結構如下:
desc t_partition;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
DATA VARCHAR2(100)
T_PARTITION以列ID間隔100分別創建了10個分區,如下
-
SQL> SELECT count(*) FROM user_tab_partitions WHERE table_name='T_PARTITION';
COUNT(*)
----------
1000
T_PARTITION的數據量情況如下:
-
SQL> SELECT count(*) FROM t_partition;
-
-
COUNT(*)
-
----------
-
11030039
2.在DATA列分別創建一個本地索引一個全局索引。
本地索引:
-
create index ind_l_data on t_partition(data) local;
-
Index created.
創建完成后,通過以下語句檢查索引的具體情況,通過輸出可以看到:如同前面說的一樣本地索引與基表分區情況一樣。
-
SELECT table_name,locality,alignment FROM user_part_indexes WHERE index_name='IND_L_DATA';
-
TABLE_NAME LOCALITY ALIGNMENT
-
---------------- ----------- ------------
-
T_PARTITION LOCAL NON_PREFIXED
-
-
SELECT count(*) FROM user_ind_partitions t WHERE index_name='IND_L_DATA';
COUNT(*)
----------
1000
全局分區索引:
-
drop index ind_l_data;
-
create index ind_g_data on test_partition(data);
-
Index created.
3.比較本地索引以及全局索引
分為兩種情況比較,一種情況查詢謂詞中帶有基表的分區鍵,另外一種不帶基表分區鍵,先看條件不帶分區鍵的情況:
本地索引:
全局索引:
通過上面兩個圖輸出的統計信息,可以看到邏輯讀(consistent gets)全局索引
明顯要比本地索引邏輯讀少,全局索引的效率更高。
下面再觀察一下謂詞中帶有分區鍵的情況:
本地索引:
全局索引:
相差不大,相對來說本地索引性能比全局索引性能更好一下。
全局索引和本地索引各自有各自的特點,使用場景不同,DBA應根據具體的業務情況創建相應的索引,另外從Oracle官方可以找到關于本地索引和全局索引的一點點建議:
由此推斷:全局索引多用于OLTP系統,而本地索引都用于OLAP系統。
維護注意事項
1.本地索引可以為前綴索引和非前綴索引,全局索引必須為前綴索引。如下我們全局索引創建在data列,通過id列分區,系統報錯GLOBAL partitioned index must be prefixed.
2.只要查詢條件中包含了基表的分區鍵,非前綴、前綴索引都支持分區消除。
3.本地索引由Oracle自動管理,當有添加、刪除、合并分區、截斷分區數據等操作,本地索引自動更新,但全局索引不會自動更新,一旦有上述操作請記得
添加update global indexes語句,若不添加索引就會變得不可用。
本地索引:
全局索引:
可以看到若不添加update global indexes,全局索引狀態會變為不可用,因此在
日常維護全局索引過程中請注意此問題。