分区表及分区索引(16)--增加和删除索引分区

来源:互联网 发布:简单的数据分析软件 编辑:程序博客网 时间:2024/05/17 02:46
全面学习分区表及分区索引(16)--增加和删除索引分区


从本节开始,介绍索引分区的管理操作~~


1、增加索引分区(Adding Index Partitions)


从语法上来讲,增加索引分区与增加表分区没有什么实际性差别,将table换成index即可:


Alter index idxname add partition ptname tbs_clause;


需要注意一点add partition只能用于hash的global索引(如果你想为range类型的索引增加分区,不要用add,split也许能帮你实际你的需求),并且add partition无法新增local索引分区,因为local分区是由索引所在基表来维护的。




下面举个操作的例子,还记的我们前面演示创建hash分区的时候创建的索引吗,这里就以它为例吧:




SQL> select partition_name ,tablespace_name  from user_ind_partitions 
  2  where index_name = 'IDX_PART_HASH_ID';
 
PARTITION_NAME                 TABLESPACE_NAME
------------------------------ ------------------------------
T_HASH_P1                      PART01
T_HASH_P2                      PART02
T_HASH_P3                      PART03


SQL> alter index idx_part_hash_id add partition i_hash_p4 tablespace part04;
 
alter index idx_part_hash_id add partition i_hash_p4 tablespace part04
 
ORA-14076: 提交的变更索引分区/子分区操作对本地分区的索引无效


为什么呢??????????????????????????
####################################################
ORA-14076: DROP/SPLIT PARTITION may not be applied to a LOCAL index partition


Cause: An attempt was made to drop or split a partition of a LOCAL index.


Action: Ensure that the index named in the DROP/SPLIT PARTITION statement is a GLOBAL partitioned index.
####################################################


SQL> select index_name ,table_name ,PARTITIONED,GLOBAL_STATS
  2  from user_indexes
  3  where index_name ='IDX_PART_HASH_ID';
 
INDEX_NAME                     TABLE_NAME                     PARTITIONED GLOBAL_STATS
------------------------------ ------------------------------ ----------- ------------
IDX_PART_HASH_ID               T_PART_HASH                    YES         NO//SO...这就是原因!!!


之前提到过,add partition只能用于hash的global索引!




SQL> drop index idx_part_hash_id;
 
Index dropped


//重建 HASH GLOBAL INDEX !(注意:global hash index 是10G新添加的,以前只有global range index!U KNOW THAT!)


SQL> create index idx_part_hash_id on t_part_hash(id)
  2  global partition by hash(id)
  3  partitions 3 store in (part01,part02,part03);
 
Index created
 
SQL> select index_name ,partition_name ,tablespace_name 
  2  from dba_ind_partitions
  3  where index_name = 'IDX_PART_HASH_ID';
 
INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
IDX_PART_HASH_ID               SYS_P84                        PART01
IDX_PART_HASH_ID               SYS_P85                        PART02
IDX_PART_HASH_ID               SYS_P86                        PART03




//继续给GLOBAL分区索引添加 分区。
SQL> alter index idx_part_hash_id add partition i_hash_4 tablespace karl_space;
 
Index altered  //OK!


SQL> select index_name ,partition_name,tablespace_name
  2  from dba_ind_partitions
  3  where index_name ='IDX_PART_HASH_ID';
 
INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
IDX_PART_HASH_ID               I_HASH_4                       KARL_SPACE
IDX_PART_HASH_ID               SYS_P84                        PART01
IDX_PART_HASH_ID               SYS_P85                        PART02
IDX_PART_HASH_ID               SYS_P86                        PART03
 
2、删除索引分区(Dropping Index Partitions)


Drop partition只能操作global索引的range分区(??????是这样吗?不能操作global的HASH分区?),语法也很简单:


Alter index idxname drop partition ptname;


看起来很简单对吧,但是,需要注意,索引必须拥有一个maxvalue的分区,该分区无法删除。


另外,如果删除的索引分区中包含数据,分区被删除后,会造成相邻的higher分区失效,需要手工编译!这个其实很容易理解,索引中数据都是经过排序的,我们drop partition删除的只是分区,但其对应的索引数据还需要有地儿存在行啊(不然索引启不就不准确了),于是就只好存储到比它更高区间值的索引区分里去了,那个分区莫名其妙多了数据,自然状态就为不可用了。




举个例子:


SQL> select table_owner,table_name,partition_name,high_value,tablespace_name
  2  from dba_tab_partitions
  3  where table_name = 'T_PART_RANGE';
 
TABLE_OWNER                    TABLE_NAME                     PARTITION_NAME                 HIGH_VALUE         TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------ ------------------ ------------------------------
KARL                           T_PART_RANGE                   T_RANGE_MAX                    MAXVALUE           PART03
KARL                           T_PART_RANGE                   T_RANGE_P1                     10                 PART01
KARL                           T_PART_RANGE                   T_RANGE_P2                     20                 PART02




SQL> create index idx_part_range_id on t_part_range(id)
  2  global partition by range(id)(
  3  partition i_p1 values less than(10) tablespace part01,
  4  partition i_p2 values less than(20) tablespace part02,
  5  partition i_max values less than(maxvalue) tablespace part03);
 
Index created
//即将删除索引分区2
SQL> select * from t_part_range partition(t_range_p2);
 
        ID NAME
---------- ----------
        11 afad
        12 asdfasd


SQL> alter index idx_part_range_id drop partition i_p2;
 
Index altered
 
 

SQL> select index_name ,partition_name,high_value,status ,tablespace_name
  2  from dba_ind_partitions
  3  where index_Name = 'IDX_PART_RANGE_ID';
 
INDEX_NAME                     PARTITION_NAME                 HIGH_VALUE        STATUS                   TABLESPACE_NAME
------------------------------ ------------------------------ ----------------- --------                 ------------------------------
IDX_PART_RANGE_ID              I_MAX                          MAXVALUE          UNUSABLE //失效!        PART03
IDX_PART_RANGE_ID              I_P1                           10                USABLE                   PART01
                                                                                        




于是,i_p1 分区就unusable了,继续往下看吧,后面要讲如何重编译索引分区了。



原创粉丝点击