分区表的常用操作对索引的影响

1、构建实验表

SQL> select *From wl;
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK                7902 17-12月-80            800                    20
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7934 MILLER     CLERK              7782 23-1月 -82           1300                    10
      8102 FORD                                             17-4月 -83
      7654 MARTIN                                          26-1月 -84

SQL> create table t2 partition by range(hiredate)
  2           (partition p1 values less than(to_date('1981-01-01','yyyy-mm-dd')) tablespace test,
  3              partition p2 values less than(to_date('1982-01-01','yyyy-mm-dd')) tablespace test,
  4              partition other values less than(maxvalue) tablespace test)
  5            as select * from wl;
表已创建。

SQL>  select table_name,partition_name,partition_position from  user_tab_partitions where table_name='T2';
TABLE_NAME                     PARTITION_NAME                 PARTITION_POSITION
------------------------------ ------------------------------ ------------------
T2                             P1                                              1
T2                             P2                                              2
T2                             P3                                              3

创建索引:

SQL> alter table t2 add constraints   pk_t2 primary key(empno);
表已更改。
SQL> create index local_ename on t2(ename) local;
索引已创建。

查看索引的状态:

SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    USABLE   P3
SQL> select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A

从上面查询结果可以看出 本地索引 usable 可用,主键 valid 也是正常状态

SQL> select *From t2 partition(p1);
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                    20
SQL> select *From t2 partition(p2);
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
SQL> select *From t2 partition(p3);
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10
      8102 FORD                            17-4月 -83
      7654 MARTIN                          26-1月 -84


                                                              split partition   对分区表索引的影响  

2、 拆分分区对分区表索引的影响

SQL> alter table t2 split partition p3 at(to_date('1983-01-01','yyyy-mm-dd')) into (partition p3,partition other);

表已更改。

SQL> select *From t2 partition(p3) ;
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10
SQL> select *From t2 partition(other);
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      8102 FORD                            17-4月 -83
      7654 MARTIN                          26-1月 -84

我们可以看到p3 和other 分区都有数据,再来查看索引的状态
SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    UNUSABLE P3
SQL>  select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             UNUSABLE
LOCAL_ENAME                    T2                             N/A

SQL> alter table t2 split partition p3 at(to_date('1983-01-01','yyyy-mm-dd')) into (partition p3,partition other);
表已更改。

从上面我们可以看出拆分成p3,other分区都有数据的情况下,分区的索引变成unusable,主键也是unusable

我们把索引rebuild好后,继续对other 分区拆分,拆分成 无数据的p4和有数据的other分区,看看索引的状态

SQL> alter index pk_t2 rebuild online;
索引已更改。

SQL> alter index local_ename  rebuild partition p3  online ;
索引已更改。

SQL>  select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A

SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    USABLE   P3

在此索引已经恢复好了,进行拆分拆分成 无数据的p4和有数据的other分区,看看索引的状态


SQL> alter table t2 split partition other at(to_date('1983-04-01','yyyy-mm-dd')) into (partition p4,partition other);
表已更改。

SQL> select *from t2 partition(p4);
未选定行
SQL> select *from t2 partition(other);
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      8102 FORD                            17-4月 -83
      7654 MARTIN                          26-1月 -84

SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    USABLE   P3
LOCAL_ENAME                    USABLE   P4
SQL>  select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A

我们可以发现当p4分区没有数据而other分区有数据的时候,本地索引和主键是好的可用状态



继续拆分,拆分成有数据的p5和无数据的other分区的时候,索引的状态


SQL> alter table t2 split partition other at(to_date('1984-04-01','yyyy-mm-dd')) into (partition p5,partition other);
表已更改。

SQL> select *from t2 partition(other);
未选定行
SQL> select *from t2 partition(p5);
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      8102 FORD                            17-4月 -83
      7654 MARTIN                          26-1月 -84
SQL>  select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A
SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    USABLE   P3
LOCAL_ENAME                    USABLE   P4
LOCAL_ENAME                    USABLE   P5


我们可以发现当p5分区有数据而other分区没有数据的时候,本地索引和主键是好的可用状态

总结:

split partition ( split partition a into a and b )
 a,b分区均无数据

a分区有数据

b分区无数据

a分区无数据

b分区有数据

a,b分区均有数 据 
global indexVALIDVALIDVALIDUNUSABLE 
local indexUSABLEUSABLEUSABLEUNUSABLE 


                                                        add partition  对索引的影响

SQL> create table t2 partition by range(hiredate)
  2          (partition p1 values less than(to_date('1981-01-01','yyyy-mm-dd')) tablespace test,
  3             partition p2 values less than(to_date('1985-01-01','yyyy-mm-dd')) tablespace test
  4            )
  5           as select * from wl;
表已创建。
SQL> alter table t2 add constraints   pk_t2 primary key(empno);
表已更改。


SQL> create index local_ename on t2(ename) local;
索引已创建。


SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
SQL> select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A


SQL> alter table t2 add partition p3 values less than(to_date('1986-01-01','yyyy-mm-dd')) tablespace test ;
表已更改。


SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    USABLE   P3


SQL> select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A

从此处可以看出添加分区对分区表索引没有任何影响


                                                       drop partition  对索引的影响

刚才新添加的分区,目前p3分区里面没有任何数据,我们删除p3分区

SQL> select  *from t2 partition(p3);
未选定行

删除分区
SQL> alter table t2 drop partition p3;
表已更改。

SQL> select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A

SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2

删除空的分区对分区表索引没有任何影响

SQL>  alter table t2 add partition p3 values less than(to_date('1986-01-01','yyyy-mm-dd')) tablespace test ;
表已更改。
SQL> insert into t2 (empno,ename,hiredate) values(7777,'aaaa',to_date('1985-07-01','yyyy-mm-dd'));
已创建 1 行。
SQL> commit;
提交完成。

SQL> select  *from t2 partition(p3);
     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7777 aaaa                            01-7月 -85

SQL>  alter table t2 drop partition p3;
表已更改。

SQL> select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             UNUSABLE
LOCAL_ENAME                    T2                             N/A

SQL>  select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2

可以发现当删除有数据的分区时候,全局索引不可以用

                                                        truncate partition  对索引的影响

SQL>  create table t2 partition by range(hiredate)
  2           (partition p1 values less than(to_date('1981-1-1','yyyy-mm-dd')) tablespace test,
  3              partition p2 values less than(to_date('1982-1-1','yyyy-mm-dd')) tablespace test,
  4              partition p3 values less than(maxvalue) tablespace test)
  5            as select * from wl;
表已创建。

SQL> alter table t2 add constraints   pk_t2 primary key(empno);
表已更改。
SQL> create index local_ename on t2(ename) local;
索引已创建。
SQL> select count(*)from t2 partition(p2);
  COUNT(*)
----------
         0
SQL> select count(*)from t2 partition(p3);
  COUNT(*)
----------
         3
SQL> select count(*)from t2 partition(p1);
  COUNT(*)
----------
         1
SQL>  select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A

SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    USABLE   P3


我们可以看到p1分区里面无数据,其他分区里面都有数据,我们对p1分区truncate 一下

SQL> alter table t2 truncate partition(p1);
表被截断。
SQL>  select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             VALID
LOCAL_ENAME                    T2                             N/A

SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    USABLE   P3

可以看出truncate一个空的分区,对于分区表的索引没有影响

SQL> alter table t2 truncate partition(p2);
表被截断。

SQL>  select    INDEX_NAME,TABLE_NAME,STATUS from dba_indexes where table_name='T2';
INDEX_NAME                     TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
PK_T2                          T2                             UNUSABLE
LOCAL_ENAME                    T2                             N/A
SQL> select INDEX_NAME,status,PARTITION_NAME from DBA_ind_partitions WHERE PARTITION_NAME LIKE 'P%' and index_owner='SCOTT' ;
INDEX_NAME                     STATUS   PARTITION_NAME
------------------------------ -------- ------------------------------
LOCAL_ENAME                    USABLE   P1
LOCAL_ENAME                    USABLE   P2
LOCAL_ENAME                    USABLE   P3

可以看出truncate一个非空的分区,对于分区表的全局索引有影响

  add partition drop partitiondrop partitiontruncate partitiontruncate  partition
  分区表中无数据分区表中有数据分区表中无数据分区表中有数据
global indexVALIDVALIDUNUSABLEVALIDUNUSABLE
local indexUSABLEUSABLEUSABLEUSABLEUSABLE

  
  





 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值