如果索引已经被使用,或将被使用,在采取行动(如删除或创建索引)之前,我们必须放聪明点。为了帮助解决这些问题,Oracle为我们提供了一个新特性,INVISIBLE索引,允许我们将索引隐藏起来,隐藏的索引不能使用,但仍然可以通过INSERT,UPDATE和DELETE 进行维护。要使一个索引不可见,可以使用CREATE或ALTER INDEX INVISIBLE命令,这里以上面的IX_EMP_SAL索引为例进行演示: SQL> create index ix_emp_sal on emp(sal) INVISIBLE;
! c7 r7 M" n- j. k* ^+ G: { SQL> alter index ix_emp_sal INVISIBLE;$ t/ k" ?% p' N2 X! T/ b8 ~
当一个索引被置为INVISIBLE时,应用程序就看不到它了,也不能在任何DML操作中使用它了。优化器也看不到隐藏索引,因此也不会被任何执行计划使用,除非明确指定了一个提示(hint),会话被设置为使用隐藏索引,或者数据库被设置为可以使用所有的隐藏索引,这正是某些DBA梦寐以求的功能,使用一个新的init.ora参数optimizer_use_invisible_indexes,你可以固定会话,或全系统范围内都可以使用隐藏索引,让你有机会测试新建索引在完全移动到生产环境之前的影响,可以通过设置这个初始化参数使用隐藏索引,或在SQL中增加提示使用隐藏索引,如:
1 w2 W u5 O/ @) p2 o* O SQL> alter system set optimizer_use_invisible_indexetrue;
# I; K* j- v- a0 {3 s4 o SQL> alter session set optimizer_use_invisible_indexetrue;6 D# m2 T" \: }/ N. v5 O2 \
SQL> select * /*+ index (emp ix_ep_sal) */ ename from emp where sal=1500;8 i3 c+ _: j% X" W3 D
要使一个索引从不可见状态变为可见状态,使用ALTER INDEX语句+ VISIBLE关键字即可:
& N9 t, Q: {: v* ~, G" s& r SQL> alter index ix_emp_sal VISIBLE;- p" g5 i$ n8 i- B- w
此外,如果你想找出在你的数据库中哪些索引是隐藏的,可以查询DBA_,USER_或ALL_INDEXES视图中的VISIBILITY列。7 b7 o3 i6 w5 ~. O4 P) z
SQL>select index_name, visibility
7 L- H) a% Z4 v from dba_indexes
5 Z7 j, S1 C7 t2 K | where index_name='IX_EMP_SAL';
- O4 f! I! [$ a' z7 a6 O8 u INDEX_NAME VISIBILIT
L4 o v& z& z: a# x/ @ -------------- ---------
. ]* i ] i% v9 S$ X7 i IX_EMP_SAL INVISIBLE
& g' I+ k& c# o6 I; f& o* { 在运用INVISIBLE索引功能时要注意由其它方法创建或修改的隐藏索引,如果你以前写有一个SQL查看索引的结构,现在需要修改一下增加检查 VISIBILITY列,否则你看到的仅仅是索引的部分信息,当执行了大量的INSERT,UPDATE或DELETE操作时,这可能会变成一个隐藏的恶梦。; w" @& D- R! g: B
索引的可用性一向有些黑色艺术,对于删除一个索引是否会对性能产生影响从来都没有明确的判断标准,现在通过监视索引的可用性,并可以修改索引的可见性,DBA完全可以更好地测试和验证索引的可用性了。 |