关于数据库索引失效的问题

[/b]一般情况,在大量数据割接完以后,会发生索引实效的情况。

查询dba_indexes表,其索引状态STATUS应该为VALID,如果是DISABLE或者unusable都为不正常索引。

如果是分区索引,可用以下语句进行查询。如下:

  select t.Index_Name, t.Partition_Name, t.Tablespace_Name, t.Status  
    from Dba_Ind_Partitions t  
   where t.Index_Name = 'INX_SERV_PROD_PRPTY_2'  

其中'INX_SERV_PROD_PRPTY_2'是索引名。

执行返回结果如下:
1 INX_SERV_PROD_PRPTY_2 PARTITION_1 RMS_INDX USABLE
2 INX_SERV_PROD_PRPTY_2 PARTITION_10 RMS_INDX USABLE
3 INX_SERV_PROD_PRPTY_2 PARTITION_11 RMS_INDX USABLE
4 INX_SERV_PROD_PRPTY_2 PARTITION_2 RMS_INDX USABLE
5 INX_SERV_PROD_PRPTY_2 PARTITION_3 RMS_INDX USABLE
6 INX_SERV_PROD_PRPTY_2 PARTITION_4 RMS_INDX USABLE
7 INX_SERV_PROD_PRPTY_2 PARTITION_5 RMS_INDX USABLE
8 INX_SERV_PROD_PRPTY_2 PARTITION_6 RMS_INDX USABLE
9 INX_SERV_PROD_PRPTY_2 PARTITION_7 RMS_INDX USABLE
10 INX_SERV_PROD_PRPTY_2 PARTITION_8 RMS_INDX USABLE
11 INX_SERV_PROD_PRPTY_2 PARTITION_9 RMS_INDX USABLE

可以查询到每个表分区的索引是否失效。

----

[b]以下原因经常导致索引状态不正常


1) alter table move

2) alter index disable

只有函数索引可以alter index disable,一般的应该是alter index unusable

3) truncate分区表上的全局索引

4) sqlldr ( parallel or direct )append 导入了重复数据但是索引有唯一约束

5) sqlldr insert /*+ append */


建议:alter index 索引名 rebuild online;

   (B-tree索引:

·索引会随着时间的增加而变的不平衡;

·删除的索引空间不会被重用;

·随着索引层数的增加,索引将会变得无效并需要重建;

·聚簇因子差,索引需要重建;

·为提高性能,索引需要经常重建;

·假如聚簇因子过大,那么重建索引可能会有好处,聚簇因子应该接近块的数量,而非行的数

)  

在上线后运行一段时期时候考虑一些大表的索引进行alter index 索引名 rebuild online 在线重建

9i以上oracle就建议用DBMS_STATS 包来代替ANALYZE 语句,如果使用ANALYZE做过分析可能会产生不是很好的分析效果

  



以下是一般不使用索引的几个常见原因:

1) 没有查询条件,或者查询条件没有建立索引

2) 在查询条件上没有使用引导列

3) 查询的数量是大表的大部分,应该是30%以上。

4) 索引本身失效

5) 查询条件使用函数在索引列上(见12)

6) 对小表查询

7) 提示不使用索引

8) 统计数据不真实

9) CBO计算走索引花费过大的情况。其实也包含了上面的情况,这里指的是表占有的block要比索引小。

10)隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误.

  由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给Oracle,这样会导致索引失效.

    错误的例子:select * from test where tu_mdn=13333333333;

    正确的例子:select * from test where tu_mdn='13333333333';

11)对索引列进行运算导致索引失效,我所指的对索引列进行运算包括(+,-,*,/,! 等)

    错误的例子:select * from test where id-1=9;

    正确的例子:select * from test where id=10;

12)使用Oracle内部函数导致索引失效.对于这样情况应当创建基于函数的索引.

    错误的例子:select * from test where round(id)=10; 说明,此时id的索引已经不起作用了

    正确的例子:首先建立函数索引,create index test_id_fbi_idx on test(round(id));

                     然后 select * from test where round(id)=10; 这时函数索引起作用了




你可能感兴趣的:(oracle)