oracle小知识点7--索引的unusable,disable,invisible

UNUSABLE Clause
When you make an index unusable, it is ignored by the optimizer and is not maintained by DML. When you make one partition of a partitioned
index unusable, the other partitions of the index remain valid.

You must rebuild or drop and re-create an unusable index or index partition before using it.

DISABLE Clause
DISABLE applies only to a function-based index. This clause lets you disable the use of a function-based index. You might want to do so,
for example, while working on the body of the function. Afterward you can either rebuild the index or specify another ALTER INDEX statement
with the ENABLE keyword.


Invisible Index
An invisible index is an index that is ignored by the optimizer unless you explicitly set the OPTIMIZER_USE_INVISIBLE_INDEXES initialization parameter
to TRUE at the session or system level.


临时禁用一个索引时,发现唯一索引置为unusable时,会影响insert操作,但函数索引和非唯一索引不会.
以下测试:
--创建测试表
SQL> create table scott.selectshen01
  2  as select * from dba_objects
  3  where object_id is not null;
Table created
--建唯一索引
SQL> create unique index scott.idx_selectshen01_01 on scott.selectshen01(object_id);
Index created
--建非唯一索引
SQL> create index scott.idx_selectshen01_02 on scott.selectshen01(data_object_id);
Index created
--建函数索引
SQL> create index scott.idx_selectshen01_03 on scott.selectshen01(lower(owner));
Index created

--设置唯一索引unusable
SQL> alter index scott.idx_selectshen01_01 unusable;
Index altered
--插入数据,报ORA-01502索引不可用.
SQL> insert into scott.selectshen01(object_id)
  2  select object_id from scott.selectshen01 where rownum<2;
insert into scott.selectshen01(object_id)
select object_id from scott.selectshen01 where rownum<2
ORA-01502: 索引 'SCOTT.IDX_SELECTSHEN01_01' 或这类索引的分区处于不可用状态
--只能删除或重建
SQL> drop index scott.idx_selectshen01_01;
Index dropped
--可以插入数据
SQL>
SQL> insert into scott.selectshen01(object_id)
  2  select object_id from scott.selectshen01 where rownum<2;
1 row inserted

--设置函数索引unusable
SQL> alter index scott.idx_selectshen01_03 unusable;
Index altered
--可以插入数据
SQL> insert into scott.selectshen01(owner)
  2  select owner from scott.selectshen01 where rownum<2;
1 row inserted
--设置非唯一索引unusable
SQL> alter index scott.idx_selectshen01_02 unusable;
Index altered
--可以插入数据
SQL> insert into scott.selectshen01(data_object_id)
  2  select data_object_id from scott.selectshen01 where rownum<2;
1 row inserted

顺便测试一下index的disable和invisible:
--只有函数索引才有disable/enable选项
SQL> alter index scott.idx_selectshen01_02 disable;
alter index scott.idx_selectshen01_02 disable
ORA-02243: ALTER INDEX 或 ALTER MATERIALIZED VIEW 选项无效
--设置函数索引disable
SQL> alter index scott.idx_selectshen01_03 disable;
Index altered
--插入数据,报30554索引被禁用
SQL> insert into scott.selectshen01(owner)
  2  select owner from scott.selectshen01 where rownum<2;
insert into scott.selectshen01(owner)
select owner from scott.selectshen01 where rownum<2
ORA-30554: 基于函数的索引SCOTT.IDX_SELECTSHEN01_03被禁用
--enable或rebuild函数索引
SQL> alter index scott.idx_selectshen01_03 enable;
Index altered
--可以插入数据
SQL> insert into scott.selectshen01(owner)
  2  select owner from scott.selectshen01 where rownum<2;
1 row inserted


--重建索引,测试visible/invisilbe
SQL> alter index scott.idx_selectshen01_02 rebuild;
Index altered
--参数optimizer_use_invisible_indexes为false
SQL> select name,value from v$parameter
  2  where name like '%visible%';
NAME                                     VALUE
--------------------------------------- ------------------------------------------
optimizer_use_invisible_indexes          FALSE

--设置索引invisible
SQL> alter index scott.idx_selectshen01_02 invisible;
Index altered

--查看sql执行计划,发现不会走这个invisible的索引
SQL> set autotrace traceonly
SQL> select * from scott.selectshen01 where data_object_id=1;

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 3630500522

--------------------------------------------------------------------------------
--

| Id  | Operation      | Name     | Rows  | Bytes | Cost (%CPU)| Time
 |

--------------------------------------------------------------------------------
--

|   0 | SELECT STATEMENT  |         |    14 |  2898 |   349   (1)| 00:00:05
 |

|*  1 |  TABLE ACCESS FULL| SELECTSHEN01 |    14 |  2898 |   349   (1)| 00:00:05
 |

--------------------------------------------------------------------------------
...
SQL> set autotrace off


--设置索引visible
SQL> alter index scott.idx_selectshen01_02 visible;
Index altered

--查看sql执行计划,发现已经走这个visible的索引
SQL> set autotrace traceonly

SQL> select * from scott.selectshen01 where data_object_id=1;

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 2125468280

--------------------------------------------------------------------------------
-------------------

| Id  | Operation            | Name          | Rows  | Bytes | Cost
 (%CPU)| Time      |

--------------------------------------------------------------------------------
-------------------

|   0 | SELECT STATEMENT        |              |    1 |   207 |
1   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| SELECTSHEN01      |    1 |   207 |
1   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN        | IDX_SELECTSHEN01_02 |    1 |      |
1   (0)| 00:00:01 |

--------------------------------------------------------------------------------

SQL> set autotrace off

备注:
1.unusable的索引需要rebuild 或 drop,re-create才能回到valid.skip_unusable_indexes为true也是无法在insert时跳过不可用的唯一索引的.
2.disable/enable只能用在函数索引中.从dba_indexes中这个值对应的列名funcidx_status也可以看出.
3.invisible仍然会在表增删改数据时,更新索引.不可见索引在性能优化时测试索引的有效性很有用,不会影响其它会话的执行计划.可以通过设置系统或会话的
optimizer_use_invisible_indexes为true,让不可见索引被使用.


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28539951/viewspace-1809364/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/28539951/viewspace-1809364/

你可能感兴趣的:(oracle小知识点7--索引的unusable,disable,invisible)