Oracle分区索引--本地索引和全局索引比较(一)

2014-11-24 18:44:07 · 作者: · 浏览: 2


分区索引分为本地(local index)索引和全局索引(global index)。


其中本地索引又可以分为有前缀(prefix)的索引和无前缀(nonprefix)的索引。而全局索引目前只支持有前缀的索引。B树索引和位图索引都可以分区,但是HASH索引不可以被分区。位图索引必须是本地索引。下面就介绍本地索引以及全局索引各自的特点来说明区别;


一、本地索引特点:




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




二、全局索引特点:


1. 全局索引的分区键和分区数和表的分区键和分区数可能都不相同,表和全局索引的分区机制不一样。


2. 全局索引可以分区,也可以是不分区索引,全局索引必须是前缀索引,即全局索引的索引列必须是以索引分区键作为其前几列。


3. 全局分区索引的索引条目可能指向若干个分区,因此,对于全局分区索引,即使只截断一个分区中的数据,都需要rebulid若干个分区甚至是整个索引。


4. 全局索引多应用于oltp系统中。


5. 全局分区索引只按范围或者散列hash分区,hash分区是10g以后才支持。


6. oracle9i以后对分区表做move或者truncate的时可以用update global indexes语句来同步更新全局分区索引,用消耗一定资源来换取高度的可用性。


7. 表用a列作分区,索引用b做局部分区索引,若where条件中用b来查询,那么oracle会扫描所有的表和索引的分区,成本会比分区更高,此时可以考虑用b做全局分区索引。



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