分区索引笔记(三)--全局分区索引
全局分区索引在一个索引分区中包含来自多个表分区的键。一个全局分区索引的分区键是分区表中不同的或指定一个范围的值。在创建全局分区索引时,必须定义分区键的范围和值。
全局索引只能是B树索引。Oracle在默认情况下不会维护全局分区索引。如果一个分区被截取、增加、分割、删除等,就必须重建全局分区索引,除非在修改表时指定ALTER TABLE命令的UPDATE GLOBAL INDEXES子句。
1、种类
(1)有前缀的索引
通常,全局有前缀索引在底层表中没有经过对等分区。没有什么因素能限制索引的对等分区,但Oracle在生成查询计划或执行分区维护操作时,并不会充分利用对等分区。如果索引被对等分区,就必须把它创建为一个本地索引,这样Oracle可以维护这个索引,并使用它来删除不必要的分区,每个分区都包含指向多个表分区中行的索引条目。
技巧:如果一个全局索引将被对等分区,就必须把它创建为一个本地索引,这样Oracle可以维护这个索引,并使用它来删除不必要的分区。
(2)无前缀的索引
到目前为止(10gR2),Oracle不支持无前缀的全局索引。
2.、注意事项:
(1)全局索引可以分区,也可以是不分区索引,全局索引必须是前缀索引,即全局索引的索引列必须是以索引分区键作为其前几列。
(2)全局索引可以依附于分区表;也可以依附于非分区表。
(3)全局分区索引的索引条目可能指向若干个分区,因此,对于全局分区索引,即使只截断一个分区中的数据,都需要rebulid若干个分区甚至是整个索引。
(4)全局索引多应用于oltp系统中。
(5)全局分区索引只按范围或者散列分区,hash分区是10g以后才支持。
(6) oracle9i 以后对分区表做move或者truncate 的时可以用update global indexes 语句来同步更新全局分区索引,用消耗一定资源来换取高度的可用性。
(7)表用a列作分区,索引用b做局部分区索引,若where条件中用b来查询,那么oracle会扫描所有的表和索引的分区,成本会比分区更高,此时可以考虑用b做全局分区索引。
3、实验
示例1 全局索引,全局索引对所有分区类型都支持:
sql> create index ix_custaddr_ global_id on custaddr(id) global;
索引已创建。
示例2:全局分区索引,只支持Range 分区和Hash 分区:
(1)创建2个测试分区表:
sql> create table pdba (id number, time date) partition by range (time)
(
partition p1 values less than (to_date('2010-10-1', 'yyyy-mm-dd')),
partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')),
partition p3 values less than (to_date('2010-12-1', 'yyyy-mm-dd')),
partition p4 values less than (maxvalue)
);
表已创建。
SQL> create table Thash
(
id number primary key,
item_id number(8) not null
)
partition by hash(id)
(
partition part_01,
partition part_02,
partition part_03
);
表已创建。
(2)创建分区索引
示例2:全局分区索引
SQL> create index i_id_global on PDBA(id) global
partition by range(id)
(partition p1 values less than (200),
partition p2 values less than (maxvalue)
);
索引已创建。
-这个是有前缀的分区索引。
SQL> create index i_time_global on PDBA(id) global
partition by range(time)
(partition p1 values less than (TO_DATE('2010-12-1', 'YYYY-MM-DD')),
partition p2 values less than (maxvalue)
);
partition by range(time)
*
第 2 行出现错误:
ORA-14038: GLOBAL 分区索引必须加上前缀
SQL> create index i_time_global on PDBA(time) global
partition by range(time)
(partition p1 values less than (TO_DATE('2010-12-1', 'YYYY-MM-DD')),
partition p2 values less than (maxvalue)
);
索引已创建。
--有前缀的分区索引
SQL> select index_name,table_name,partitioning_type,locality,ALIGNMENT from
user_part_indexes where table_name='PDBA';
index_name table_name partition locali alignment
------------------------------ ---------- --------- ------ ------------
i_id_global pdba range global prefixed
i_time_global pdba range global prefixed
SQL> CREATE INDEX ix_hash ON PDBA (id,time) GLOBAL
2 PARTITION BY HASH (id)
3 (PARTITION p1,
4 PARTITION p2,
5 PARTITION p3,
6 PARTITION p4);
索引已创建。
只要索引的引导列包含分区键,就是有前缀的分区索引。