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

在日常的维护中,经常会出现索引失效的情况,什么情况会导致索引失效呢?通过查阅资料总结如下:

一般情况,在大量数据割接完以后,会发生索引实效的情况。
查询dba_indexes表,其索引状态STATUS应该为VALID,如果是DISABLE或者unusable都为不正常索引。

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

selectt.Index_Name,t.Partition_Name,t.Tablespace_Name,t.Status
fromDba_Ind_Partitionst
wheret.Index_Name='INX_SERV_PROD_PRPTY_2'

其中'INX_SERV_PROD_PRPTY_2'是索引名。

执行返回结果如下:
1INX_SERV_PROD_PRPTY_2PARTITION_1RMS_INDXUSABLE
2INX_SERV_PROD_PRPTY_2PARTITION_10RMS_INDXUSABLE
3INX_SERV_PROD_PRPTY_2PARTITION_11RMS_INDXUSABLE
4INX_SERV_PROD_PRPTY_2PARTITION_2RMS_INDXUSABLE
5INX_SERV_PROD_PRPTY_2PARTITION_3RMS_INDXUSABLE
6INX_SERV_PROD_PRPTY_2PARTITION_4RMS_INDXUSABLE
7INX_SERV_PROD_PRPTY_2PARTITION_5RMS_INDXUSABLE
8INX_SERV_PROD_PRPTY_2PARTITION_6RMS_INDXUSABLE
9INX_SERV_PROD_PRPTY_2PARTITION_7RMS_INDXUSABLE
10INX_SERV_PROD_PRPTY_2PARTITION_8RMS_INDXUSABLE
11INX_SERV_PROD_PRPTY_2PARTITION_9RMS_INDXUSABLE

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

----
以下原因经常导致索引状态不正常

1)altertablemove

2)alterindexdisable

只有函数索引可以alterindexdisable,一般的应该是alterindexunusable

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


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

5)sqlldrinsert/*+append*/


建议:alterindex索引名rebuildonline;

(B-tree
索引:


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

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

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

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

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

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

)

在上线后运行一段时期时候考虑一些大表的索引进行alterindex索引名rebuildonline在线重建

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*fromtestwheretu_mdn=13333333333;

正确的例子:
select*fromtestwheretu_mdn='13333333333';

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

错误的例子:
select*fromtestwhereid-1=9;

正确的例子:
select*fromtestwhereid=10;

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

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


正确的例子:首先建立函数索引,createindextest_id_fbi_idxontest(round(id));

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

你可能感兴趣的:(oracle,数据库)