分区索引分为全局索引和本地索引
其中本地索引又可以分为有前缀(prefix)的索引和无前缀(nonprefix)的索引。而全局索引目前只支持有前缀的索引。B树索引和位图索引都可以分区,但是HASH索引不可以被分区。位图索引必须是本地索引。
一般使用LOCAL索引较为方便,而且维护代价较低,并且LOCAL索引是在分区的基础上去创建索引,类似于在一个子表内部去创建索引,这样开销主要是区分分区上,很规范的管理起来,在OLAP系统中应用很广泛;而相对的GLOBAL索引是全局类型的索引,根据实际情况可以调整分区的类别,而并非按照分区结构一一定义,相对维护代价较高一些,在OLTP环境用得相对较多
一:本地索引:创建了一个分区表后,如果需要在表上面创建索引,并且索引的分区机制和表的分区机制一样,那么这样的索引就叫做本地分区索引。本地索引是由ORACLE自动管理的,它分为有前缀的本地索引和无前缀的本地索引。什么叫有前缀的本地索引?有前缀的本地索引就是包含了分区键,并且将其作为引导列的索引。什么叫无前缀的本地索引?无前缀的本地索引就是没有将分区键的前导列作为索引的前导列的索引。下面举例说明:
create table test (id number,data varchar2(100))
partition by RANGE (id)
(
partition p1 values less than (1000) tablespace p1,
partition p2 values less than (2000) tablespace p2,
partition p3 values less than (maxvalue) tablespace p3
);
create index i_id on test(id) local; 因为id是分区键,所以这样就创建了一个有前缀的本地索引。
SQL> select dbms_metadata.get_ddl('INDEX','I_ID','ROBINSON') index_name FROM DUAL; ------去掉了一些无用信息
INDEX_NAME
--------------------------------------------------------------------------------
CREATE INDEX "ROBINSON"."I_ID" ON "ROBINSON"."TEST" ("ID") LOCAL
(PARTITION "P1" TABLESPACE "P1" , PARTITION "P2" TABLESPACE "P2" ,PARTITION "P3" TABLESPACE "P3" );
也可以这样创建:
SQL> drop index i_id;
Index dropped
SQL> CREATE INDEX "ROBINSON"."I_ID" ON "ROBINSON"."TEST" ("ID") LOCAL
2 (PARTITION "P1" TABLESPACE "P1" , PARTITION "P2" TABLESPACE "P2" ,PARTITION "P3" TABLESPACE "P3" );
Index created
create index i_data on test(data) local;因为data不是分区键,所以这样就创建了一个无前缀的本地索引。
SQL> select dbms_metadata.get_ddl('INDEX','I_DATA','ROBINSON') index_name FROM DUAL; ---我删除了一些无用信息
INDEX_NAME
--------------------------------------------------------------------------------
CREATE INDEX "ROBINSON"."I_DATA" ON "ROBINSON"."TEST" ("DATA") LOCAL
(PARTITION "P1" TABLESPACE "P1" ,PARTITION "P2" TABLESPACE "P2" , PARTITION "P3" TABLESPACE "P3" );
从user_part_indexes视图也可以证明刚才创建的索引,一个是有前缀的,一个是无前缀的
SQL> select index_name,table_name,partitioning_type,locality,ALIGNMENT from user_part_indexes;
INDEX_NAME TABLE_NAME PARTITIONING_TYPE LOCALITY ALIGNMENT
------------------------------ ------------------------------ ----------------- -------- ------------
I_DATA TEST RANGE LOCAL NON_PREFIXED
I_ID TEST RANGE LOCAL PREFIXED
二:全局索引:与本地分区索引不同的是,全局分区索引的分区机制与表的分区机制不一样。全局分区索引全局分区索引只能是B树索引,到目前为止(10gR2),oracle只支持有前缀的全局索引。另外oracle不会自动的维护全局分区索引,当我们在对表的分区做修改之后,如果执行修改的语句不加上update global indexes的话,那么索引将不可用。以刚才创建的分区表test为例,讲解全局分区索引
SQL> drop index i_id ;
Index dropped
SQL> create index i_id_global on test(id) global
2 partition by range(id)
3 ( partition p1 values less than (2000) tablespace p1,
4 partition p2 values less than (maxvalue) tablespace p2
5 );
Index created
SQL> alter table test drop partition p3;
Table altered
ORACLE默认不会自动维护全局分区索引,注意看status列,
SQL> select INDEX_NAME,PARTITION_NAME,STATUS from user_ind_partitions where index_name='I_ID_GLOBAL';
INDEX_NAME PARTITION_NAME STATUS
------------------------------ ------------------------------ --------
I_ID_GLOBAL P1 USABLE
I_ID_GLOBAL P2 USABLE
SQL> create index i_id_global on test(data) global
2 partition by range(id)
3 ( partition p1 values less than (2000) tablespace p1,
4 partition p2 values less than (maxvalue) tablespace p2
5 );
create index i_id_global on test(data) global
partition by range(id)
( partition p1 va