分區表的什么操作會導致索引失效-測試


分區表的什么操作會導致索引失效

Why index became invalid? (Doc ID 1576700.1)    
APPLIES TO:
Oracle Database - Enterprise Edition - Version 11.2.0.2 and later

GOAL
Indexes should have status as VALID to become usable by queries however sometimes it may have
status as UNUSABLE and this note explains those causes. SOLUTION Indexes can become invalid or unusable whenever a DBA tasks shifts the ROWID values, thereby requiring an index rebuild.
These DBA tasks that shift table ROWID
's include: Table partition maintenance - Alter commands (move, split or truncate partition) will shift ROWID's,
making the index invalid and unusable.
CTAS maintenance - Table reorganization with "alter table move" or an online table reorganization
(using the dbms_redefinition package) will shift ROWIDs, creating unusable indexes. Oracle imports - An Oracle import (imp utility) with the skip_unusable_indexes=y parameter SQL*Loader (sqlldr utility) - Using direct path loads (e.g. skip_index_maintenance) will cause invalid and unusable indexes --參考bisal bisal的個人雜貨鋪,刪除分區如何不讓全局索引失效? CREATE TABLE interval_sale ( prod_id NUMBER(6) , cust_id NUMBER , time_id DATE ) PARTITION BY RANGE (time_id) INTERVAL(NUMTOYMINTERVAL(1, 'YEAR')) ( PARTITION p0 VALUES LESS THAN (TO_DATE('1-1-2003', 'DD-MM-YYYY')), PARTITION p1 VALUES LESS THAN (TO_DATE('1-1-2004', 'DD-MM-YYYY')), PARTITION p2 VALUES LESS THAN (TO_DATE('1-1-2005', 'DD-MM-YYYY')), PARTITION p3 VALUES LESS THAN (TO_DATE('1-1-2006', 'DD-MM-YYYY'))); SQL> insert into interval_sale values(1, 1, to_date('2002-01-01','yyyy-mm-dd')); SQL> insert into interval_sale values(2, 2, to_date('2003-01-01','yyyy-mm-dd')); SQL> insert into interval_sale values(3, 3, to_date('2004-01-01','yyyy-mm-dd')); SQL> insert into interval_sale values(4, 4, to_date('2005-01-01','yyyy-mm-dd')); SQL> commit; 創建全局索引,當前狀態是VALID SQL> create index idx_01 on interval_sale(cust_id); SQL> select table_name, index_name, partitioned, status from user_indexes where table_name='INTERVAL_SALE'; TABLE_NAME INDEX_NAME PAR STATUS ------------------------------ ------------------------------ --- -------- INTERVAL_SALE IDX_01 NO VALID 刪除第一個分區 SQL> alter table interval_sale drop partition for (to_date('2002-01-01','yyyy-mm-dd')); 此時,看到這個全局索引是UNUSABLE的狀態,和我們的設想是相同的,即刪除分區,會導致全局索引的失效 SQL> select table_name, index_name, partitioned, status from user_indexes where table_name='INTERVAL_SALE'; TABLE_NAME INDEX_NAME PAR STATUS ------------------------------ ------------------------------ --- -------- INTERVAL_SALE IDX_01 NO UNUSABLE ---刪除數據 SQL> alter index idx_01 rebuild online; SQL> delete from interval_sale where time_id <= to_date('2003-01-01','yyyy-mm-dd'); SQL> commit; --再刪除分區操作 SQL> alter table interval_sale drop partition for (to_date('2003-01-01','yyyy-mm-dd')); 此時,再看全局索引,他的狀態正常,VALID,並未因為分區刪除的操作,導致其失效 SQL> select table_name, index_name, status from user_indexes where table_name='INTERVAL_SALE'; TABLE_NAME INDEX_NAME STATUS ------------------------------ ------------------------------ -------- INTERVAL_SALE IDX_01 VALID 應用場景反思? 此測試如何更好的用於實踐,設想一個場景; 一個很大的分區表,並且存在主鍵列索引,非分區及全局索引,需要刪除歷史分區。 並且歷史分區數據不大的情況下,先delete數據后,再刪除分區是最好的,因為不用整體維護索引。 如何判斷具體的分區數據 select count(*) as 記錄數 from 表名 partition(分區名) ;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM