Czy Klauzula UPDATE INDEXES W Instrukcji DDL Odświeża Lokalne I Globalne Indeksy
Jakakolwiek modyfikacja na partycjach powoduje unieważnienie indeksów przypisanych do partycji, a co za tym idzie wymusza konieczność przebudowy tych indeksów. Czy można się tego wystrzec stosując klauzulę UPDATE INDEXES? Odpowiedź poniżej.
Poniższy kod przygotowuje tabelę, indeksy (zarówno lokalne jak i globalne) jak i nabija tabelę danymi do testu. Jak widać poniżej zarówno indeks lokalny jak i globalny mają statusy sugerujące ich prawidłowość, co jest jak najbardziej prawidłowe.
DROP TABLE T1 / CREATE TABLE T1(id NUMBER, descr VARCHAR2(100)) PARTITION BY RANGE(id) ( PARTITION p1 VALUES LESS THAN (100), PARTITION p2 VALUES LESS THAN (200), PARTITION p3 VALUES LESS THAN (MAXVALUE) ) / CREATE INDEX idx_local on t1(id) local / CREATE INDEX idx_global on t1(descr) --default: global / INSERT INTO t1 SELECT ROWNUM, CASE WHEN MOD(ROWNUM, 2) = 0 THEN 'A' ELSE 'B' END FROM dual CONNECT BY ROWNUM <= 300 / COMMIT /
SELECT index_name, status FROM dba_indexes WHERE table_name = 'T1' /
INDEX_NAME STATUS
---------- ------
IDX_LOCAL N/A <-- to jest prawidłowe, index jest partycjonowany, więc status znajduje się w dba_ind_partitions
IDX_GLOBAL VALID
SELECT index_name, high_value, partition_position, status FROM dba_ind_partitions WHERE index_name IN (SELECT index_name FROM dba_indexes WHERE table_name = 'T1') /
INDEX_NAME HIGH_VALUE PARTITION_POSITION STATUS
---------- ---------- ------------------ ------
IDX_LOCAL 100 1 USABLE
IDX_LOCAL 200 2 USABLE
IDX_LOCAL MAXVALUE 3 USABLE
Poniższy kod przebudowuje partycję P1 i umożliwi sprawdzenie, jak po takiej instrukcji zachowają się indeksy.
ALTER TABLE T1 MOVE PARTITION P1 / SELECT index_name, status FROM dba_indexes WHERE table_name = 'T1' /
INDEX_NAME STATUS
---------- ------
IDX_LOCAL N/A
IDX_GLOBAL UNUSABLE
SELECT index_name, high_value, partition_position, status FROM dba_ind_partitions WHERE index_name IN (SELECT index_name FROM dba_indexes WHERE table_name = 'T1') /
INDEX_NAME HIGH_VALUE PARTITION_POSITION STATUS
---------- ---------- ------------------ ------
IDX_LOCAL 100 1 UNUSABLE
IDX_LOCAL 200 2 USABLE
IDX_LOCAL MAXVALUE 3 USABLE
Statusy prawidłowo wskazują, że na partycji P1 miały miejsce jakieś działania, ale nie odświeżono indeksów. Potwierdziło to, zresztą słusznie, że samo polecenie ALTER TABLE w żaden sposób nie nakazuje działań na indeksach.
Do dalszych działań konieczne jest odświeżenie indeksów, aby uzyskać stan indeksów jak na początku.
ALTER INDEX idx_global REBUILD / ALTER INDEX idx_local REBUILD PARTITION P1 / ALTER TABLE T1 MOVE PARTITION P1 UPDATE INDEXES / SELECT index_name, status FROM dba_indexes WHERE table_name = 'T1' /
INDEX_NAME STATUS
---------- ------
IDX_LOCAL N/A
IDX_GLOBAL VALID
SELECT index_name, high_value, partition_position, status FROM dba_ind_partitions WHERE index_name IN (SELECT index_name FROM dba_indexes WHERE table_name = 'T1') /
INDEX_NAME HIGH_VALUE PARTITION_POSITION STATUS
---------- ---------- ------------------ ------
IDX_LOCAL 100 1 USABLE
IDX_LOCAL 200 2 USABLE
IDX_LOCAL MAXVALUE 3 USABLE
Reasumując. Klauzula UPDATE INDEXES w poleceniu ALTER TABLE odświeża zarówno indeksy lokalne jak i globalne. Nie dzieje się to jednak bezkosztowo, bo taki zabieg kosztuje dodatkowy czas i zasoby i jeżeli wymogiem nie jest wydajność to warto z niej korzystać.
Szymon
Komentarze |0|
Tagi: ALTER TABLE, GLOBAL INDEX, INDEX, LOCAL INDEX, PARTITION, TABLE, UNUSABLE