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



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

  1. 加载温度表
  2. 使用源表交换分区
  3. 重建本地索引
  4. 重建全局索引

但是,问题是重建索引需要大量时间,这使得源表不可用 在此期间。源表是支持实时应用的非常关键的表。 由于这种情况,使用此表的 Web 服务将出现超时异常。

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

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

您可以找到日常作业的代码截取,以及源表 (TABLEX) 和临时表的结构 (TABLEX_TEMP)

日常工作:

' 创建或替换过程

X.LOAD__TABLES_X
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;`

表和索引的结构:

'

创建表X.TABLEX_TEMP ( CUST_NO号(9), 名称 VARCHAR2(54 字节), 姓氏VARCHAR2(100字节), 性爱瓦查尔(1字节) IDNO号码(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);

'

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

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

  • 进行分区交换之前,您应该在临时表上构建相同的本地索引。然后,您必须将 INCLUDE 索引附加到 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 文档以了解详细信息:

  • 自动更新索引
  • 更改表

最新更新