交换分区后如何避免在源 table 上重建索引
How to avoid index rebuild on source table after exchange partition
我有一份日常工作,这份工作基本上是在做
- 负载温度table
- 与源交换分区 table
- 重建本地索引
- 重建全局索引
但是,问题是重建索引需要很多时间,这使得源 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 官方文档以了解详细信息:
我有一份日常工作,这份工作基本上是在做
- 负载温度table
- 与源交换分区 table
- 重建本地索引
- 重建全局索引
但是,问题是重建索引需要很多时间,这使得源 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 官方文档以了解详细信息: