索引维护是 DBA 的一项重要工作。当一个系统运行很长一段时间,经过需求变更、结构设
计变化后,系统中就可能会存在一些不会被使用的索引,或者使用效率很低的索引。这些
索引的存在,不仅占用系统空间,而且会降低事务效率,增加系统的 waits。因此,我们
需要找出那些无用或低效索引的索引并删除它们(找出无用索引可以通过索引监控的方法)。
但是,直接删除索引还是存在一定风险的。例如,某些索引可能只是在一些周期的作
业中被使用到,而如果监控周期没有覆盖到这些作业的触发点,就会认为索引是无用的而
被删除。当作业启动后,可能就会对系统性能造成冲击。这时,可能就会手忙脚乱的去找
回索引定义语句、重建索引。
11g 之前,我们可以先不删除索引,而将其修改为 unusable。这样的话,索引的定
义并未删除,只是索引不能再被使用也不会随着表数据的更新而更新。当需要重新使用该
索引时,需要用 rebuild 语句重建、然后更新统计信息。对于一些大表来说,这个时间可
能就非常长。
在 11g 里,oracle 提供了一个新的特性来降低直接删除索引或者禁用索引的风险,
那就是索引不可见(Index Invisible)。我们可以在创建索引时指定 invisible 属性或者用
alter 语句来修改索引为 invisible。
SQL 代码
SQL> create index t_test1_idx on t_test1(table_name) invisible;
Index created.
SQL> alter index t_test1_idx invisible;
Index altered.
当索引被设为不可见后,实际上就是指该索引对于优化器不可见,而索引的正常更新
并不受影响——即表在增、删、改时,索引也会被更新。只是当优化器在选择查询计划时
会“无视”该索引(无论是 CBO 或 RBO):
SQL 代码
SQL> create table t_test1 as select * from dba_tables;
Table created.
SQL> create index t_test1_idx on t_test1(table_name);
Index created.
SQL> analyze table t_test1 compute statistics for table for all indexes;
Table analyzed.
SQL> set autot trace exp
SQL> select * from t_test1 where table_name like 'HR%';
no rows selected