在oracle10g,索引的状态一般是valid:表示正常状态,unusable或invalid表示不可用状态,是由于索引的rowid发生的改变导致的。
以下几种情况下,会导致索引的状态变为invalid或unusable,需要手动rebuild。
- 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.
oracle11g现在多了一种状态invisible不可见索引 。创建的不可见索引优化器是看不到的,除非将OPTIMIZER_USE_INVISIBLE_INDEXES 设置为TURE,这个值默认为False。
使索引不可见是使索引不可用或删除索引的一种替代办法。使用不可见的索引,可完成以下操作:
(1) 在删除索引之前测试对索引的删除。
(2) 对应用程序的特定操作或模块使用临时索引结构,这样就不会影响整个应用程序。
注意:
与不可用的索引不同,不可见的索引在使用DML 语句期间仍会得到维护。
dba_indexes视图中增加了visibility来确定索引是否可见。
下面做个测试:
SQL> create table invisible_test as select * from dba_tables;
Table created.
SQL> create index i_in_test on invisible_test(owner,table_name);
Index created.
SQL> set autotrace traceonly;
SQL> set linesize 1000
SQL> select * from invisible_test where owner='L5M' and table_name='COMPANY';
Execution Plan
----------------------------------------------------------
Plan hash value: 2725340964
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 503 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| INVISIBLE_TEST | 1 | 503 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I_IN_TEST | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
正常情况下优化器是走索引的。
扫描二维码关注公众号,回复:
2808192 查看本文章
现将这个索引Invisible:
SQL> alter index I_IN_TEST invisible;
Index altered.
SQL> select visibility from dba_indexes where index_name='I_IN_TEST';
VISIBILIT
---------
INVISIBLE
SQL> select * from invisible_test where owner='L5M' and table_name='COMPANY';
Execution Plan
----------------------------------------------------------
Plan hash value: 1952212210
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 503 | 33 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| INVISIBLE_TEST | 1 | 503 | 33 (0)| 00:00:01 |
------------------------------------------------------------------------------------
索引不可见后,执行计划就走了全表扫描。