1.当查询语句中使用<>,!=,^= 等非的操作时,数据库将不使用索引,可以使用 in or 或>重写。记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中。
2.is null和is not null数据库将不适用索引(除非索引是一个位图索引)。
3.比较不匹配的数据类型
比如,account_number是一个VARCHAR2类型,在account_number字段上有索引。
下面的语句将执行全表扫描select bank_name,address,city,state,zip from banks where account_number = 990354;
因为 Oracle可以自动把where子句变成to_number(account_number)=990354,这样就限制了索引的使用,改成下面的查询就可以使用索引:
select bank_name,address,city,state,zip from banks where account_number ='990354';
4. 使用函数(基于函数的索引除外)时,数据库也将不使用索引。比如,‘ ¦ ¦'是字符连接函数. 就象其他函数那样, 停用了索引;‘+'是数学函数. 就象其他数学函数那样, 停用了索引。
5.相同的索引列不能互相比较,这将会启用全表扫描。比如,可以在表中创建基于函数的索引。如果没有基于函数的索引,任何在列上执行了函数的查询都不能使用这个列的索引。例如,下面的查询就不能使用JOB列上的索引,除非它是基于函数的索引:
select * from emp where UPPER(job) = 'MGR';
下面的查询使用JOB列上的索引,但是它将不会返回JOB列具有Mgr或mgr值的行:
select * from emp where job = 'MGR';
可以创建这样的索引,允许索引访问支持基于函数的列或数据。可以对列表达式UPPER(job)创建索引,而不是直接在JOB列上建立索引,如:
create index EMP$UPPER_JOB on emp(UPPER(job));
6.带通配符(%,出现在开始)的like语句。比如,要求在职工表中查询名字中包含cliton的人。可以采用如下的查询SQL语句:
select * from employee where last_name like '%cliton%';
这里由于通配符(%)在搜寻词首出现,所以Oracle系统不使用last_name的索引。在很多情况下可能无法避免这种情况,但是一定要心中有底,通配符如此使用会降低查询速度。然而当通配符出现在字符串其他位置时,优化器就能利用索引。在下面的查询中索引得到了使用:
select * from employee where last_name like 'c%'。
7.如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引. 这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引 。