分区索引分为全局索引和本地索引 其中本地索引又可以分为有前缀(prefix)的索引和无前缀(nonprefix)的索引。而全局索引目前只支持有前缀的索引。B树索引和位图索引都可以分区,但是HASH索引不可以被分区。位图索引必须是本地索引。 一般使用LOCAL索引较为方便
分区索引分为全局索引和本地索引
其中本地索引又可以分为有前缀(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 values less than (2000) tablespace p1,
partition p2 values less than (maxvalue) tablespace p2
)
ORA-14038: GLOBAL 分区索引必须加上前缀
SQL> create bitmap 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 );
create bitmap index i_id_global on test(id) global
partition by range(id)
( partition p1 values less than (2000) tablespace p1,
partition p2 values less than (maxvalue) tablespace p2
)
ORA-25113: GLOBAL 可能无法与位图索引一起使用
三:分区索引不能够将其作为整体重建,必须对每个分区重建
SQL> alter index i_id_global rebuild online nologging;
alter index i_id_global rebuild online nologging
ORA-14086: 不能将分区索引作为整体重建
这个时候可以查询dba_ind_partitions,或者user_ind_partitions,找到partition_name,然后对每个分区重建
SQL> select index_name,partition_name from user_ind_partitions where index_name='I_ID_GLOBAL';
INDEX_NAME PARTITION_NAME
------------------------------ ------------------------------
I_ID_GLOBAL P1
I_ID_GLOBAL P2
SQL> alter index i_id_global rebuild partition p1 online nologging;
Index altered
SQL> alter index i_id_global rebuild partition p2 online nologging;
Index altered
四、建立分区索引与普通索引的区别1、建立普通的索引
create index no_part_idx on p_list(sale_date);
2、建立本地分区索引
create index local_part_idx on p_list(sale_date) local;
3、建立全局分区索引
create index glo_part_idx on p_list(sale_date) global partition by range(sale_date) (
PARTITION p1 VALUES less than ('20121111') TABLESPACE system,
PARTITION p2 VALUES less than ('20121112') TABLESPACE system,
PARTITION pmax VALUES less than (maxvalue) TABLESPACE system );
四、删除索引与索引失效:
对于分区索引的删除,local index 不能指定分区名称,需单独的删除分区索引。 local index 对应的分区会伴随着data分区的删除而一起被删除。globalpartition index 可以指定分区名称,删除某一分区。但是有一点要注意,如果该分区不为空,则会导致更高一级的索引分区被置为UNUSABLE 。
ALTER INDEX gidx_range_exampel_id drop partition part_01 此句将导致part_02 状态为UNUSABLE
本地分区索引的状态改变
--整个索引不可用
ALTER INDEX index_tmp_partition_list UNUSABLE;
--单个分区索引不可用
ALTER INDEX index_tmp_partition_list MODIFY PARTITION p_20110816 USABLE;
--分区不可用之后,需要重建索引
alter index index_tmp_partition_list rebuild partition p_20110816;
--查看分区索引的状态
select index_name,partition_name,tablespace_name,status
fromuser_ind_partitions wherelower(index_name)='index_tmp_partition_list'
参考自:http://blog.csdn.net/robinson1988/article/details/5276924