Как избежать перестройки индекса по исходной таблице после обмена
У меня есть ежедневная работа, и эта работа делает в основном
- LOAD Temp таблица
- Раздел Exchange с исходной таблицей
- Перестройте локальные индексы
- Перестройте глобальные индексы
Однако проблема в том, что перестройка индексов занимает много времени, и это делает исходную таблицу недоступной в течение этого периода. Исходная таблица является очень важной таблицей для поддержки приложений в реальном времени. Из-за этого веб-службы, использующие эту таблицу, получают исключения тайм-аута.
Есть ли у меня какой-либо альтернативный способ, а не строить эти индексы на исходной таблице?
Любая помощь или обсуждение очень ценится.
Вы можете найти фрагмент кода ежедневной работы, а также структуру исходной таблицы (TABLEX) и временной таблицы (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;`
Структура таблиц и индексов:
`
CREATE TABLE X.TABLEX_TEMP (CUST_NO NUMBER (9), NAME VARCHAR2 (54 байта), SARNAME VARCHAR2(100 байт), SEX VARCHAR (1 байт), IDNO NUMBER (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);
`
1 ответ
Что ж, поскольку обмен разделами изменяет существенную часть данных, индекс становится непригодным для использования. Однако вы можете избежать невозможности использования индекса, обновив индексы во время обмена разделами.
По моему опыту лучше всего использовать двухэтапный подход:
- Перед обменом разделами вы должны построить те же локальные индексы для временной таблицы. Затем вы должны добавить 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 для деталей: