这篇文章给大家介绍几种SQL查询时索引可能失效的情况。
(1) like查询时以%开头索引失效,以%结尾可以索引有效。比如
select * from T where name like '%w' 失效
select * from T where name like 'w%' 有效
(2) 含有隐式转换时,比如你的SELECT * FROM T WHERE Y = 5 在Y上面有一个索引,但是Y列是VARCHAR2的,那么Oracle会将上面的5进行一个隐式的转换,SELECT * FROM T WHERE TO_NUMBER(Y) = 5,这个时候也是有可能用不到索引的。
(3) 使用函数或者四则运算时会失效。
select * from SoftWareDetailInfo where SoftUseLine +0= 0 失效
(4) 条件中有or的可能会失效。
如果是这样一个查询
SELECT * FROM TB WHERE A=1 AND B>2 AND C<3 AND D IN (4,5,6)
并且在TB表上有这样一个索引:CREATE INDEX INX_TB_ABCD ON TB (A,B,C,D)
那么这个查询可以用到这个索引
如果同样是这个索引,查询换成
SELECT * FROM TB_ WHERE A=1 OR B>2 OR C<3 OR D IN (4,5,6)
那么这个查询就用不到上面那个索引,因为结果集是几个条件的并集,最多只能在查找A=1的数据时用索引,其它几个条件都需要表扫描,那优化器就会选择直接走一遍表扫描,所以索引就失效了。
那么像第二个查询这样的应该怎么建索引呢,答案就是四个列上各建一个索引,或者只在选择性最高的列上建索引,比如A=1的数据量很少,就在A上建,如果D是4,5,6的数据很少,就在D上建,这样优化器就会选择先走索引查找,再对找出的结果集进行筛选,扫描数就会大幅减少。
(5) 对于多列索引,不是使用的第一部分,则不会使用索引
(6) 判断索引列是否不等于某个值时。‘!=’操作符。比如:select * from SoftWareDetailInfo where SoftUseLine != 0