由于交换分区采用的是修改元数据的方式,并不对物理数据做迁移,所以导致交换分区后索引失效
创建分区表
create table p(a NUMBER, b NUMBER , c varchar2(20),d varchar2(20))
partition by range(b)
(partition p1 values less than(100),
partition p2 values less than(200) ,
partition p3 values less than(300));
创建主键在a列
alter table p add constraint pk_p_a primary key(a);
创建local索引在b列
create index l_p_b on p(b) local;
创建global索引在c列
create index g_p_c on p(c)
GLOBAL PARTITION BY hash (c)
(partition pg1,partition pg2);
创建普通索引在d列
create index i_p_d on p(d);
创建普通表t
create table t(a NUMBER, b NUMBER , c varchar2(20),d varchar2(20));
创建主键
alter table t add constraint pk_t_a primary key(a);
如果a列没主键在执行EXCHANGE 时会报ORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE PARTITION。
两表插入数据
insert into p values(1,11,'a','aa');
insert into p values(2,111,'b','bb');
insert into t values(3,222,'c','cc');Commit;
查询索引状态
SQL> select INDEX_NAME,STATUS from dba_indexes where table_name='P';
INDEX_NAME STATUS
------------------------------ --------
PK_P_A VALID
L_P_B N/A
G_P_C N/A
I_P_D VALID
查询local索引状态
SQL> select INDEX_NAME ,STATUS,a.partition_name from dba_ind_partitions a where index_name='L_P_B';
INDEX_NAME STATUS PARTITION_NAME
------------------------------ -------- ------------------------------
L_P_B USABLE P1
L_P_B USABLE P2
L_P_B USABLE P3
查询global索引状态
SQL> select INDEX_NAME ,STATUS,a.partition_name from dba_ind_partitions a where index_name='G_P_C';
INDEX_NAME STATUS PARTITION_NAME
------------------------------ -------- ------------------------------
G_P_C USABLE PG1
G_P_C USABLE PG2
SQL> select INDEX_NAME,STATUS from dba_indexes where table_name='T';
INDEX_NAME STATUS
------------------------------ --------
PK_T_A VALID
交换分区操作
ALTER TABLE p EXCHANGE PARTITION p3 WITH TABLE t ;
检查索引状态
SQL> select INDEX_NAME,STATUS from dba_indexes where table_name='P';
INDEX_NAME STATUS
------------------------------ --------
PK_P_A UNUSABLE
L_P_B N/A
G_P_C N/A
I_P_D UNUSABLE
SQL> select INDEX_NAME ,STATUS,a.partition_name from dba_ind_partitions a where index_name='L_P_B';
INDEX_NAME STATUS PARTITION_NAME
------------------------------ -------- ------------------------------
L_P_B USABLE P1
L_P_B USABLE P2
L_P_B UNUSABLE P3
SQL> select INDEX_NAME ,STATUS,a.partition_name from dba_ind_partitions a where index_name='G_P_C';
INDEX_NAME STATUS PARTITION_NAME
------------------------------ -------- ------------------------------
G_P_C UNUSABLE PG1
G_P_C UNUSABLE PG2
SQL> select INDEX_NAME,STATUS from dba_indexes where table_name='T';
INDEX_NAME STATUS
------------------------------ --------
PK_T_A UNUSABLE
结果:除了未被交换的分区的local类型索引有效,其它索引均失效。
重置数据
truncate table t;
truncate table p;
--注:表被truncate后索引状态会自动正常
insert into p values(1,11,'a','aa');
insert into p values(2,111,'b','bb');
insert into t values(3,222,'c','cc');Commit;
使用update indexes子句交换分区
ALTER TABLE p EXCHANGE PARTITION p3 WITH TABLE t update indexes;
检查索引状态
SQL> select INDEX_NAME,STATUS from dba_indexes where table_name='P';
INDEX_NAME STATUS
------------------------------ --------
PK_P_A VALID
L_P_B N/A
G_P_C N/A
I_P_D VALID
SQL> select INDEX_NAME ,STATUS,a.partition_name from dba_ind_partitions a where index_name='L_P_B';
INDEX_NAME STATUS PARTITION_NAME
------------------------------ -------- ------------------------------
L_P_B USABLE P1
L_P_B USABLE P2
L_P_B UNUSABLE P3
SQL> select INDEX_NAME ,STATUS,a.partition_name from dba_ind_partitions a where index_name='G_P_C';
INDEX_NAME STATUS PARTITION_NAME
------------------------------ -------- ------------------------------
G_P_C USABLE PG1
G_P_C USABLE PG2
SQL> select INDEX_NAME,STATUS from dba_indexes where table_name='T';
INDEX_NAME STATUS
------------------------------ --------
PK_T_A UNUSABLE
结果:分区表的主键索引、普通索引和全局索引状态都是正常的。被交换分区的local索引和普通表的主键索引都失效了。
重置数据
truncate table t;
truncate table p;
--注:表被truncate后索引状态会自动正常
insert into p values(1,11,'a','aa');
insert into p values(2,111,'b','bb');
insert into t values(3,222,'c','cc');Commit;
普通表在b列添加索引
Create index i_t_b on t(b);
使用update indexest和including indexes子句交换分区
ALTER TABLE p EXCHANGE PARTITION p3 WITH TABLE t including indexes update indexes;
结果:ORA-14098: index mismatch for tables in ALTER TABLE EXCHANGE PARTITION
解决方案
使用update indexes子句交换分区可以最大的保证索引可用性。
使用update indexes子句执行完后分区表的主键索引、普通索引和全局索引状态都是正常的。被交换分区的local索引和普通表的索引都失效。