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

Posted plluoye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分区表的操作对索引的影响相关的知识,希望对你有一定的参考价值。

一直知道对分区表的DDL 操作可能导致索引失效,但是还没做过总结,今天稍微总结下。

  • 增加分区对所有索引都没影响
  • Truncate 分区会导致全局索引,主键失效。分区索引不受影响
  • Truncate update global indexes 索引不受影响
  • Move 分区导致全局索引和分区所在的本地索引失效。
  • Move update global indexes 全局索引没影响,分区所在的本地索引失效.
  • Drop 分区导致全局索引失效,分区索引不受影响
  • Drop upgrade global indexes 分区所有索引都不受影响
以上结论看出,分区表操作较为复杂,每次操作完都应该检查验证索引是否失效。
SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE STATUS=‘UNUSABLE‘;
SELECT INDEX_NAME,PARTITION_NAME,STATUS FROM USER_IND_PARTITIONS WHERE STATUS=‘UNUSABLE‘;
 

1.建表

create table test_part
(
  ID NUMBER(20) not null,
  REMARK VARCHAR2(1000),
  create_time DATE
)
PARTITION BY RANGE (CREATE_TIME) INTERVAL (numtoyminterval(1, year))
(partition part_t01 values less than(to_date(2018-11-01, yyyy-mm-dd)));

--创建主键
alter table test_part add constraint INDEX_PK primary key (ID) using INDEX;
--创建全局索引
create index INDEX_1 on TEST_PART (REMARK); 
--创建本地索引
create index INDEX_2 on TEST_PART (create_time) LOCAL; 

2.增加分区对索引的影响

INSERT INTO test_part VALUES(1,1,TO_DATE(20181001,YYYYMMDD));
INSERT INTO test_part VALUES(2,2,TO_DATE(20181101,YYYYMMDD));
INSERT INTO test_part VALUES(3,3,TO_DATE(20181201,YYYYMMDD));
INSERT INTO test_part VALUES(4,4,TO_DATE(20191201,YYYYMMDD));

COL HIGH_VALUE FOR A100
SELECT PARTITION_NAME,HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME=TEST_PART;

PARTITION_NAME       HIGH_VALUE
-------------------- ----------------------------------------------------------------------------------------------------
PART_T01             TO_DATE( 2018-11-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIA
SYS_P52              TO_DATE( 2019-11-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIA
SYS_P53              TO_DATE( 2020-11-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIA

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       VALID
INDEX_1                        VALID
INDEX_2                        N/A

SQL> SELECT INDEX_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_2                        USABLE
INDEX_2                        USABLE
INDEX_2                        USABLE   

可见,增加分区对所有索引都没影响

3.Truncate分区对索引的影响

SQL> alter table TEST_PART truncate partition PART_T01;

Table truncated.

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       UNUSABLE
INDEX_1                        UNUSABLE
INDEX_2                        N/A

SQL> SELECT INDEX_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_2                        USABLE
INDEX_2                        USABLE
INDEX_2                        USABLE

Truncate 分区会导致全局索引,主键失效。分区索引不受影响

4.Truncate update global indexes

SQL> alter index INDEX_PK rebuild online;

Index altered.

SQL> alter index INDEX_1 rebuild online;

Index altered.

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       VALID
INDEX_1                        VALID
INDEX_2                        N/A

SQL> alter table TEST_PART truncate partition SYS_P52 update global indexes;

Table truncated.

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       VALID
INDEX_1                        VALID
INDEX_2                        N/A

Truncate update global indexes 对索引无影响

5. Move 分区对索引的影响

 

INSERT INTO test_part VALUES(1,1,TO_DATE(20181001,YYYYMMDD));
INSERT INTO test_part VALUES(2,2,TO_DATE(20181101,YYYYMMDD));
INSERT INTO test_part VALUES(3,3,TO_DATE(20181201,YYYYMMDD));

SQL> ALTER TABLE TEST_PART MOVE PARTITION PART_T01;

Table altered.

SQL>  SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       UNUSABLE
INDEX_1                        UNUSABLE
INDEX_2                        N/A

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       UNUSABLE
INDEX_1                        UNUSABLE
INDEX_2                        N/A

SQL> SELECT INDEX_NAME,PARTITION_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

INDEX_NAME                     PARTITION_NAME       STATUS
------------------------------ -------------------- --------
INDEX_2                        PART_T01             UNUSABLE
INDEX_2                        SYS_P52              USABLE
INDEX_2                        SYS_P53              USABLE

 move 分区会导致全局索引和分区所在的本地索引失效。

6.Move update global indexes对索引的影响

1.修复:
==================
alter index INDEX_PK rebuild online;
alter index INDEX_1 rebuild online;
alter index INDEX_2 rebuild partition PART_T01 online;

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       VALID
INDEX_1                        VALID
INDEX_2                        N/A

SQL>  SELECT INDEX_NAME,PARTITION_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

INDEX_NAME                     PARTITION_NAME       STATUS
------------------------------ -------------------- --------
INDEX_2                        PART_T01             USABLE
INDEX_2                        SYS_P52              USABLE
INDEX_2                        SYS_P53              USABLE

2.Move 分区
==================
SQL> ALTER TABLE TEST_PART MOVE PARTITION PART_T01 update global indexes;

Table altered.

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       VALID
INDEX_1                        VALID
INDEX_2                        N/A

SQL>  SELECT INDEX_NAME,PARTITION_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

INDEX_NAME                     PARTITION_NAME       STATUS
------------------------------ -------------------- --------
INDEX_2                        PART_T01             UNUSABLE
INDEX_2                        SYS_P52              USABLE
INDEX_2                        SYS_P53              USABLE
Move update global indexes 全局索引没影响,分区索引部分失效.

7. Move Compress 分区对索引的影响

ALTER INDEX INDEX_2 REBUILD PARTITION PART_T01 ONLINE;
ALTER TABLE TEST_PART COMPRESS PARTITION PART_T01;
ALTER TABLE TEST_PART MOVE PARTITION PART_T01 COMPRESS FOR OLTP;
结果同 5. move 分区

8. Drop 分区对索引的影响

alter index INDEX_PK rebuild online;
alter index INDEX_1 rebuild online;
alter index INDEX_2 rebuild partition PART_T01 online;
SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;
SELECT INDEX_NAME,PARTITION_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

SQL> ALTER TABLE TEST_PART DROP PARTITION PART_T01;
ALTER TABLE TEST_PART DROP PARTITION PART_T01
                                     *
ERROR at line 1:
ORA-14758: Last partition in the range section cannot be dropped

SQL> COL HIGH_VALUE FOR A100
SQL> SELECT PARTITION_NAME,HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME=TEST_PART;

PARTITION_NAME       HIGH_VALUE
-------------------- ----------------------------------------------------------------------------------------------------
PART_T01             TO_DATE( 2018-11-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIA
SYS_P52              TO_DATE( 2019-11-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIA
SYS_P53              TO_DATE( 2020-11-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIA

第一个分区不能被删除

ALTER TABLE TEST_PART DROP PARTITION SYS_P53;

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       UNUSABLE
INDEX_1                        UNUSABLE
INDEX_2                        N/A

SQL> SELECT INDEX_NAME,PARTITION_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

INDEX_NAME                     PARTITION_NAME       STATUS
------------------------------ -------------------- --------
INDEX_2                        PART_T01             USABLE
INDEX_2                        SYS_P52              USABLE

Drop 分区导致全局索引失效,分区索引不受影响

9. Drop update global indexes 分区对索引的影响

alter index INDEX_PK rebuild online;
alter index INDEX_1 rebuild online;
alter index INDEX_2 rebuild partition PART_T01 online;
SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;
SELECT INDEX_NAME,PARTITION_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

ALTER TABLE TEST_PART DROP PARTITION SYS_P52 UPDATE GLOBAL INDEXES;

SQL> SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE TABLE_NAME=TEST_PART;

INDEX_NAME                     STATUS
------------------------------ --------
INDEX_PK                       VALID
INDEX_1                        VALID
INDEX_2                        N/A

SQL> SELECT INDEX_NAME,PARTITION_NAME,STATUS FROM USER_IND_PARTITIONS WHERE INDEX_NAME=INDEX_2;

INDEX_NAME                     PARTITION_NAME       STATUS
------------------------------ -------------------- --------
INDEX_2                        PART_T01             USABLE

Drop upgrade global indexes 分区所有索引都不受影响

以上是关于分区表的操作对索引的影响的主要内容,如果未能解决你的问题,请参考以下文章

使用C++的函数memset()时要注意它的操作对象是每一个字节

一些我容易混淆的知识(关于数组的操作对字符串的操作)

jquery的引入入口函数选择器对内容的操作对元素的操作属性操作

索罗斯的操作对区块链意味着什么?

Oracle索引梳理系列- 直方图使用技巧及analyze table操作对直方图统计的影响(谨慎使用)

elasticsearch index 功能源码概述