在SQL优化内容中有一种说法说的是避免在索引列上使用函数、运算等操作,否则Oracle优化器将不使用索引而使用全表扫描,但是也有一些例外的情况,我们来看看该灵异事件。
  一般而言,以下情况都会使Oracle的优化器走全表扫描,举例:
  1.         substr(hbs_bh,1,4)=’5400’,优化处理:hbs_bh like ‘5400%’
  2.         trunc(sk_rq)=trunc(sysdate), 优化处理:sk_rq>=trunc(sysdate) and sk_rq<trunc(sysdate+1)
  3.         进行了显式或隐式的运算的字段不能进行索引,如:
  ss_df+20>50,优化处理:ss_df>30
  'X' || hbs_bh>’X5400021452’,优化处理:hbs_bh>'5400021542'
  sk_rq+5=sysdate,优化处理:sk_rq=sysdate-5
  4.         条件内包括了多个本表的字段运算时不能进行索引,如:ys_df>cx_df,无法进行优化
  qc_bh || kh_bh='5400250000',优化处理:qc_bh='5400' and kh_bh='250000'
  5.  避免出现隐式类型转化
  hbs_bh=5401002554,优化处理:hbs_bh='5401002554',注:此条件对hbs_bh 进行隐式的to_number转换,因为hbs_bh字段是字符型。
  有一些其它的例外情况,如果select 后边只有索引列且where查询中的索引列含有非空约束的时候,以上规则不适用,如下示例:
  先给出所有脚本及结论:
  drop table t  purge;
  Create Table t  nologging As select *  from    dba_objects d ;
  create   index ind_objectname on  t(object_name);
  select t.object_name from t where t.object_name ='T';        --走索引
  select t.object_name from t where UPPER(t.object_name) ='T';       --不走索引
  select t.object_name from t where UPPER(t.object_name) ='T' and t.object_name IS NOT NULL ;           --走索引  (INDEX FAST FULL SCAN)
  select t.object_name from t where UPPER(t.object_name) ||'AAA' ='T'||'AAA' and t.object_name IS NOT NULL ;     --走索引  (INDEX FAST FULL SCAN)
  select t.object_name,t.owner from t where UPPER(t.object_name) ||'AAA' ='T'||'AAA' and t.object_name IS NOT NULL ;     --不走索引
  测试代码:
C:Users华荣>sqlplus lhr/lhr@orclasm
SQL*Plus: Release 11.2.0.1.0 Production on 星期三 11月 12 10:52:29 2014
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options
SQL>
SQL>
SQL> drop table t  purge;
表已删除。
SQL> Create Table t  nologging As select *  from    dba_objects d ;
表已创建。
SQL>  create   index ind_objectname on  t(object_name);
索引已创建。