索引的无效状态--unusable

http://space.itpub.net/14130873/viewspace-683909 
在某些大规模的数据迁移中,为了缩短迁移的时间,在源数据已满足约束条件的情况下,载入数据时为了避免多余的约束校验及创建index entry,缩短迁移时间,往往需要禁用约束和索引。对于索引的禁用如何实现呢?对于普通的B*Tree索引,可以将其状态置为unusable状态,是索引不可用,当索引不可用时,其表对dml语句的可用性还和参数skip_unusable_indexes相关。在10.2.0.1上的实验如下:

1.在skip_unusable_indexes=true的情况下:

JCQ0> conn / as sysdba
已连接。
JCQ0> show parameter indexes

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
skip_unusable_indexes                boolean     TRUE
JCQ0> conn test/test
已连接。

JCQ0> select INDEX_NAME,INDEX_TYPE,UNIQUENESS,STATUS from user_indexes where table_name='TEST';

INDEX_NAME                     INDEX_TYPE                  UNIQUENES STATUS
------------------------------ --------------------------- --------- --------
PK_TEST                        NORMAL                      UNIQUE    UNUSABLE

JCQ0> alter index pk_test unusable;

索引已更改。

JCQ0> select * from test;

未选定行

JCQ0> desc test
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------

 ID                                        NOT NULL NUMBER

JCQ0> insert into test values(1);
insert into test values(1)
*
第 1 行出现错误:
ORA-01502: 索引 'TEST.PK_TEST' 或这类索引的分区处于不可用状态

JCQ0> alter index pk_test rebuild;

索引已更改。

JCQ0> insert into test values(1);

已创建 1 行。

JCQ0> commit;

提交完成。

1.1. 在禁用唯一索引的情况下,数据无法插入,但可以进行查询

JCQ0> create table test1(id number);

表已创建。

JCQ0> create index test1_idx on test1(id);

索引已创建。

JCQ0> alter index test1_idx unusable;

索引已更改。

JCQ0> insert into test1 values(1);

已创建 1 行。

JCQ0> commit;

提交完成。

1.2. 在禁用非唯一索引的情况下,数据可以插入,也可以查询

2. 在参数skip_unusable_indexes=false的情况下

JCQ0> conn / as sysdba
已连接。
JCQ0> show parameter indexes

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
skip_unusable_indexes                boolean     TRUE
JCQ0> alter system set skip_unusable_indexes=false;

系统已更改。

JCQ0> conn test/test
已连接。
JCQ0> select * from test1;

        ID
----------
         1

JCQ0> insert into test values(2);

已创建 1 行。

JCQ0> commit;

提交完成。

2.1. 使用非唯一索引与1.2情况完全相同

JCQ0> alter index pk_test unusable;

索引已更改。

JCQ0> select * from test;
select * from test
*
第 1 行出现错误:
ORA-01502: 索引 'TEST.PK_TEST' 或这类索引的分区处于不可用状态


JCQ0> select index_name,status from user_indexes where table_name in(
  2  'TEST','TEST1');

INDEX_NAME                     STATUS
------------------------------ --------
TEST1_IDX                      UNUSABLE
PK_TEST                        UNUSABLE

JCQ0> select * from test1;

        ID
----------
         1

2.2 使用唯一索引时,无法插入数据,无法对数据进行查询

参数skip_unusable_indexes对非唯一索引的行为没有任何影响,但是在使用唯一索引时,若参数为true将无法对表进行普通的查询。
无论参数的true false与否,都无法对unusable状态的非唯一索引的表进行插入操作。
另外,对于基于函数的索引,可以将其状态置为disable,其行为与skip_unusable_indexes=true时的唯一索引有雷同之处,之后再进行详细讨论。
以上实验基于10.2.0.1版本,在9i中该参数仅在session级别有效。