交换分区后如何避免在源 table 上重建索引

How to avoid index rebuild on source table after exchange partition

我有一份日常工作,这份工作基本上是在做

  1. 负载温度table
  2. 与源交换分区 table
  3. 重建本地索引
  4. 重建全局索引

但是,问题是重建索引需要很多时间,这使得源 table 不可用 在这段时期。 source table 非常关键 table 以支持实时应用程序。 由于这种情况,使用此 table 的 Web 服务会出现超时异常。

除了在源 table 上构建此索引之外,我还有其他方法吗?

非常感谢任何帮助或讨论。

你可以找到日常工作的代码片段,以及源table(TABLEX)和临时table的结构 (TABLEX_TEMP)

日常工作:

` 创建或替换程序 X.LOAD__TABLES_X IS

BEGIN


EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLEX_TEMP REUSE STORAGE';
   INSERT /*+ APPEND */ INTO TABLEX_TEMP(CUST_NO ,IDNO,SEX,NAME,SURNAME)
   SELECT CUST_NO ,IDNO,SEX,NAME,SURNAME,PHONE
FROM T_X WHERE MAINT !='D';
COMMIT;

EXECUTE IMMEDIATE 'ALTER TABLE TABLEX EXCHANGE PARTITION DUMMY WITH TABLE TABLEX_TEMP WITHOUT VALIDATION';
EXECUTE IMMEDIATE 'ALTER TABLE TABLEX MODIFY PARTITION DUMMY REBUILD UNUSABLE LOCAL INDEXES';
EXECUTE IMMEDIATE 'ALTER INDEX PK_CUST_NO REBUILD NOCOMPRESS NOPARALLEL TABLESPACE TS_X_INDEX';
EXECUTE IMMEDIATE 'ALTER INDEX PK_CUST_NO_TMP REBUILD NOCOMPRESS NOPARALLEL TABLESPACE TS_X_INDEX';
EXECUTE IMMEDIATE 'ALTER INDEX IDX_TABLEX REBUILD NOCOMPRESS NOPARALLEL TABLESPACE TS_X_INDEX';
EXECUTE IMMEDIATE 'ALTER INDEX IDX_TABLEX_TMP REBUILD NOCOMPRESS NOPARALLEL TABLESPACE TS_X_INDEX';
EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLEX_TEMP REUSE STORAGE';

COMMIT;
END LOAD_TABLES_X;`

表和索引的结构:

`

创建 TABLE X.TABLEX_TEMP ( CUST_NO 数字 (9), 名称 VARCHAR2(54 字节), 姓氏 VARCHAR2(100 字节), 性别 VARCHAR(1 字节) 编号(11)

)
TABLESPACE TS_X_DATAA
RESULT_CACHE (MODE DEFAULT)
PCTUSED    0
PCTFREE    0
INITRANS   1
MAXTRANS   255
STORAGE    (
        INITIAL          8M
        NEXT             1M
        MINEXTENTS       1
        MAXEXTENTS       UNLIMITED
        PCTINCREASE      0
        BUFFER_POOL      DEFAULT
        FLASH_CACHE      DEFAULT
        CELL_FLASH_CACHE DEFAULT
       )
LOGGING 
COMPRESS FOR QUERY HIGH 
NOCACHE
NOPARALLEL
MONITORING;


CREATE INDEX X.IDX_TABLEX_TMP ON X.TABLEX_TEMP
(IDNO)
NOLOGGING
TABLESPACE TS_X_INDEX
PCTFREE    10
INITRANS   2
MAXTRANS   255
STORAGE    (
        INITIAL          64K
        NEXT             1M
        MINEXTENTS       1
        MAXEXTENTS       UNLIMITED
        PCTINCREASE      0
        BUFFER_POOL      DEFAULT
        FLASH_CACHE      DEFAULT
        CELL_FLASH_CACHE DEFAULT
       )
NOPARALLEL;


CREATE UNIQUE INDEX X.PK_CUST_NO_TMP ON X.TABLEX_TEMP
(CUST_NO)
NOLOGGING
TABLESPACE TS_X_INDEX
PCTFREE    10
INITRANS   2
MAXTRANS   255
STORAGE    (
        INITIAL          64K
        NEXT             1M
        MINEXTENTS       1
        MAXEXTENTS       UNLIMITED
        PCTINCREASE      0
        BUFFER_POOL      DEFAULT
        FLASH_CACHE      DEFAULT
        CELL_FLASH_CACHE DEFAULT
       )
NOPARALLEL;


ALTER TABLE X.TABLEX_TEMP ADD (
  CONSTRAINT PK_CUST_NO_TMP
  PRIMARY KEY
  (CUST_NO)
  USING INDEX X.PK_CUST_NO_TMP
   ENABLE NOVALIDATE);

 ----------------------------------------------------------

CREATE TABLE X.TABLEX
 (
   CUST_NO       NUMBER(9),
   NAME            VARCHAR2(54 BYTE),
   SURNAME         VARCHAR2(100 BYTE),
   SEX              VARCHAR (1 BYTE)
   IDNO            NUMBER(11)
 )
COMPRESS FOR QUERY HIGH 
TABLESPACE TS_X_DATA
RESULT_CACHE (MODE DEFAULT)
PCTUSED    0
PCTFREE    0
INITRANS   1
MAXTRANS   255
STORAGE    (
        BUFFER_POOL      DEFAULT
        FLASH_CACHE      DEFAULT
        CELL_FLASH_CACHE DEFAULT
       )
PARTITION BY RANGE (CUST_NO)
(  
   PARTITION DUMMY VALUES LESS THAN (999999999)
   LOGGING
   COMPRESS FOR QUERY HIGH 
    TABLESPACE TS_X_DATA
    PCTFREE    0
    INITRANS   1
    MAXTRANS   255
    STORAGE    (
            INITIAL          64K
            NEXT             1M
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            BUFFER_POOL      DEFAULT
            FLASH_CACHE      DEFAULT
            CELL_FLASH_CACHE DEFAULT
           )
   )
 NOCACHE
 NOPARALLEL
 MONITORING;


 CREATE INDEX X.IDX_TABLEX ON X.TABLEX
 (IDNO)
 NOLOGGING
 TABLESPACE TS_X_INDEX
 PCTFREE    10
 INITRANS   2
 MAXTRANS   255
 STORAGE    (
        INITIAL          64K
        NEXT             1M
        MINEXTENTS       1
        MAXEXTENTS       UNLIMITED
        PCTINCREASE      0
        BUFFER_POOL      DEFAULT
        FLASH_CACHE      DEFAULT
        CELL_FLASH_CACHE DEFAULT
       )
 NOPARALLEL;


 CREATE UNIQUE INDEX X.PK_CUST_NO ON X.TABLEX
 (CUST_NO)
 NOLOGGING
 TABLESPACE TS_X_INDEX
 PCTFREE    10
 INITRANS   2
 MAXTRANS   255
 STORAGE    (
        INITIAL          64K
        NEXT             1M
        MINEXTENTS       1
        MAXEXTENTS       UNLIMITED
        PCTINCREASE      0
        BUFFER_POOL      DEFAULT
        FLASH_CACHE      DEFAULT
        CELL_FLASH_CACHE DEFAULT
       )
 NOPARALLEL;



 ALTER TABLE X.TABLEX ADD (
   CONSTRAINT PK_CUST_NO
   PRIMARY KEY
   (CUST_NO)
   USING INDEX X.PK_CUST_NO
   ENABLE NOVALIDATE);

`

好吧,由于分区交换修改了大部分数据,因此索引必须变得不可用。但是,您可以通过在分区交换期间更新索引来避免索引变得不可用。

根据我的经验,最好使用两步法:

  • 在分区交换之前,您应该在临时 table 上构建相同的本地索引。然后您必须将 INCLUDING INDEXES 附加到 ALTER TABLE 命令。
  • 如果您确实必须使用全局索引,您可以在分区交换期间通过将 UPDATE GLOBAL INDEXES 附加到 ALTER TABLE 命令来更新它们。这将确保全局索引在整个操作期间不会不可用。

所以你整个语句会变成这样:

ALTER TABLE TABLEX EXCHANGE PARTITION DUMMY WITH TABLE TABLEX_TEMP INCLUDING INDEXES WITHOUT VALIDATION UPDATE GLOBAL INDEXES;

您可能需要查看 Oracle 官方文档以了解详细信息: