首页 > 数据库 > Oracle > 正文

ORACLE SQL性能优化系列 (十)

2024-08-29 13:30:39
字体:
来源:转载
供稿:网友
  • 本文来源于网页设计爱好者web开发社区http://www.html.org.cn收集整理,欢迎访问。

  • 31.       强制索引失效

     

      

    如果两个或以上索引具有相同的等级,你可以强制命令oracle优化器使用其中的一个(通过它,检索出的记录数量少) .

     

    举例:

      

    select ename

    from emp

    where empno = 7935 

    and deptno + 0 = 10    /*deptno上的索引将失效*/

    and emp_type || ‘’ = ‘a’  /*emp_type上的索引将失效*/

     

    这是一种相当直接的提高查询效率的办法. 但是你必须谨慎考虑这种策略,一般来说,只有在你希望单独优化几个sql时才能采用它.

     

    这里有一个例子关于何时采用这种策略,

     

    假设在emp表的emp_type列上有一个非唯一性的索引而emp_class上没有索引.

     

    select ename

    from emp

    where emp_type = ‘a’

    and emp_class = ‘x’;

     

    优化器会注意到emp_type上的索引并使用它. 这是目前唯一的选择. 如果,一段时间以后, 另一个非唯一性建立在emp_class上,优化器必须对两个索引进行选择,在通常情况下,优化器将使用两个索引并在他们的结果集合上执行排序及合并. 然而,如果其中一个索引(emp_type)接近于唯一性而另一个索引(emp_class)上有几千个重复的值. 排序及合并就会成为一种不必要的负担. 在这种情况下,你希望使优化器屏蔽掉emp_class索引.

    用下面的方案就可以解决问题.

    select ename

    from emp

    where emp_type = ‘a’

    and emp_class||’’ = ‘x’;

     

    32.       避免在索引列上使用计算.

    where子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描.

     

    举例:

     

    低效:

    select …

    from dept

    where sal * 12 > 25000;

     

    高效:

    select …

    from dept

    where sal  > 25000/12;

     

    译者按:

    这是一个非常实用的规则,请务必牢记

     

    33.       自动选择索引

    如果表中有两个以上(包括两个)索引,其中有一个唯一性索引,而其他是非唯一性.

    在这种情况下,oracle将使用唯一性索引而完全忽略非唯一性索引.

     

    举例:

    select ename

    from emp

    where empno = 2326 

    and deptno  = 20 ;

     

    这里,只有empno上的索引是唯一性的,所以empno索引将用来检索记录.

    table access by rowid on emp

           index unique scan on emp_no_idx

     

    34.       避免在索引列上使用not

    通常, 我们要避免在索引列上使用not, not会产生在和在索引列上使用函数相同的

    影响. 当oracle”遇到”not,他就会停止使用索引转而执行全表扫描.

       举例:

     

       低效: (这里,不使用索引)

     

       select …

       from dept

       where dept_code not = 0;

      

       高效: (这里,使用了索引)

     

      select …

       from dept

       where dept_code > 0;

     

       需要注意的是,在某些时候, oracle优化器会自动将not转化成相对应的关系操作符.

       not >  to  <=

       not >=  to  <

       not <  to  >=

       not <=  to  >

     

     

    译者按:

         在这个例子中,作者犯了一些错误. 例子中的低效率sql是不能被执行的.

    我做了一些测试:

        

    sql> select * from emp where not empno > 1;

    no rows selected

    execution plan

    ----------------------------------------------------------

       0      select statement optimizer=choose

       1    0   table access (by index rowid) of 'emp'

       2    1     index (range scan) of 'empno' (unique)    

     

    sql> select * from emp where empno <= 1;

    no rows selected

    execution plan

    ----------------------------------------------------------

       0      select statement optimizer=choose

       1    0   table access (by index rowid) of 'emp'

       2    1     index (range scan) of 'empno' (unique)

     

          两者的效率完全一样,也许这符合作者关于” 在某些时候, oracle优化器会自动将not转化成相对应的关系操作符” 的观点.

         

    35.       用>=替代>

     

    如果deptno上有一个索引,

     

    高效:

     

       select *

       from emp

       where deptno >=4

      

       低效:

     

       select *

       from emp

       where deptno >3

     

          两者的区别在于, 前者dbms将直接跳到第一个dept等于4的记录而后者将首先定位到deptno=3的记录并且向前扫描到第一个dept大于3的记录.
    发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表