1、查询谓词没有使用索引的主要边界,换句话说就是SELECT *可能会导致不走索引。
比如:SELECT * FROM T1 WHERE C1 = ‘XXX’;假如你的T1表上有一个包含C1值的组合索引,但是优化器会认为需要一行行的扫描会更有效,这个时候,优化器可能会选择TABLE ACCESS FULL,但是如果换成SELECT C1 FROM T1 WHERE C1 = ‘XXX’;优化器会直接去索引中找到C1的值,因为从B树中就可以找到相应的值。
2、单键值的B树索引列上存在null值,导致COUNT()不能走索引。
比如:在B树索引中有一个空值,那么查询SELECT COUNT() FROM T1;的时候,因为HASHSET中不能存储空值,所以优化器不会走索引,有两种方式可以让索引有效,一种是SELECT COUNT(*) FROM T1 WHERE XXX IS NOT NULL;或者把这个字段的属性改为not null。
3、索引列上有函数运算,导致不走索引。
比如:SELECT * FROM T1 WHERE EXTRACT(YEAR FROM C1) = ‘XXX’;即使在T1表上有一个索引包含C1字段,这个时候索引也不会被用到,因为你要查询的列中所有的行都要被计算一遍,因此要效率提高的话,在这个表上建立一个基于函数的索引,比如CREATE INDEX IDX_T1 ON T1 (EXTRACT(YEAR FROM C1));这种方式相当于Oracle会建立一个存储所有函数计算结果的值,再进行查询的时候就不需要进行计算了,因为很多函数存在不同返回值,因此必须标明这个函数是有固定返回值。
4、隐式转换导致不走索引(索引不适用于隐式转换的情况)。
比如:SELECT * FROM T1 WHERE C1 = ‘5’;在C1上面有一个索引,但是C1列是VARCHAR2的,那么Oracle会将5进行一个隐式的转换 SELECT * FROM T1 WHERE TO_NUMBER(C1) = ‘5’;这个时候也是有可能用不到索引的。
5、表的数据量小或者需要选择大部分数据,不走索引。
在Oracle的初始化参数中,有一个参数是一次读取的数据块的数目,比如你的表只有几个数据块大小,而且可以被Oracle一次性抓取,那么就没有使用索引的必要了,因为抓取索引还需要去根据rowid从数据块中获取相应的元素值,因此在表特别小的情况下,索引没有用到是情理当中的事情。
6、CBO优化器下统计信息不准确,导致不走索引。
大量的增、改、删数据,或者很久没有重新收集表信息,在数据字典中,表的统计信息是不准确的,这个情况下,可能会使用错误的索引,这个效率可能也是比较低的。
7、!=或者<>(不等于),可能导致不走索引,也可能走INDEX FAST FULL SCAN。
比如:SELECT C1 FROM T1 WHERE C1 <> ‘100’;
来源:CSDN
作者:vip9472
链接:https://blog.csdn.net/u010704614/article/details/104144655