ORACLE SQL性能优化系列 (十三)

原创 2003年09月03日 22:43:00

43.       WHERE替代ORDER BY<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

ORDER BY 子句只在两种严格的条件下使用索引.

 

ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.

ORDER BY中所有的列必须定义为非空.

 

WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列.

 

例如:

      DEPT包含以下列:

 

        <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />

DEPT_CODE    PK
    NOT NULL

        DEPT_DESC           NOT NULL

        DEPT_TYPE           NULL

   

       非唯一性的索引(DEPT_TYPE)

 

     低效: (索引不被使用)

            SELECT DEPT_CODE

            FROM DEPT

            ORDER BY DEPT_TYPE

 

       EXPLAIN PLAN:

            SORT ORDER BY

                  TABLE ACCESS FULL

 

     高效: (使用索引)

 

           SELECT DEPT_CODE

           FROM DEPT

        WHERE DEPT_TYPE > 0

  

 EXPLAIN PLAN:

      TABLE ACCESS BY ROWID ON EMP

             INDEX RANGE SCAN ON DEPT_IDX

译者按:

      ORDER BY 也能使用索引! 这的确是个容易被忽视的知识点. 我们来验证一下:

SQL>  select * from emp order by empno;

Execution Plan

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

   0      SELECT STATEMENT Optimizer=CHOOSE

   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'EMP'

   2    1     INDEX (FULL SCAN) OF 'EMPNO' (UNIQUE)

 

44.       避免改变索引列的类型.

当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换.

 

假设 EMPNO是一个数值类型的索引列.

 

SELECT …

FROM EMP

WHERE EMPNO = ‘123’

 

实际上,经过ORACLE类型转换, 语句转化为:

SELECT …

FROM EMP

WHERE EMPNO = TO_NUMBER(‘123’)

 

幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变.

 

现在,假设EMP_TYPE是一个字符类型的索引列.

SELECT …

FROM EMP

WHERE EMP_TYPE = 123

 

这个语句被ORACLE转换为:

SELECT …

FROM EMP

WHERE TO_NUMBER(EMP_TYPE)=123

 

因为内部发生的类型转换, 这个索引将不会被用到!

译者按:

为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来. 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型.

 

45.       需要当心的WHERE子句

某些SELECT 语句中的WHERE子句不使用索引. 这里有一些例子.

在下面的例子里, ‘!=’ 将不使用索引. 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中.

不使用索引:

SELECT ACCOUNT_NAME

FROM TRANSACTION

WHERE AMOUNT !=0;

使用索引:

SELECT ACCOUNT_NAME

FROM TRANSACTION

WHERE AMOUNT >0;

 

下面的例子中, ‘||’是字符连接函数. 就象其他函数那样, 停用了索引.

不使用索引:

SELECT ACCOUNT_NAME,AMOUNT

FROM TRANSACTION

WHERE ACCOUNT_NAME||ACCOUNT_TYPE=’AMEXA’;

使用索引:

SELECT ACCOUNT_NAME,AMOUNT

FROM TRANSACTION

WHERE ACCOUNT_NAME = ‘AMEX’

AND  ACCOUNT_TYPE=’ A’;

 

下面的例子中, ‘+’是数学函数. 就象其他数学函数那样, 停用了索引.

不使用索引:

SELECT ACCOUNT_NAME, AMOUNT

FROM TRANSACTION

WHERE AMOUNT + 3000 >5000;

使用索引:

SELECT ACCOUNT_NAME, AMOUNT

FROM TRANSACTION

WHERE AMOUNT > 2000 ;

下面的例子中,相同的索引列不能互相比较,这将会启用全表扫描.

不使用索引:

SELECT ACCOUNT_NAME, AMOUNT

FROM TRANSACTION

WHERE ACCOUNT_NAME = NVL(:ACC_NAME,ACCOUNT_NAME);

使用索引:

SELECT ACCOUNT_NAME, AMOUNT

FROM TRANSACTION

WHERE ACCOUNT_NAME LIKE NVL(:ACC_NAME,’%’);

 

译者按:

如果一定要对使用函数的列启用索引, ORACLE新的功能: 基于函数的索引(Function-Based Index) 也许是一个较好的方案.

 CREATE INDEX EMP_I ON EMP (UPPER(ename)); /*建立基于函数的索引*/

 SELECT * FROM emp WHERE UPPER(ename) = ‘BLACKSNAIL’; /*将使用索引*/

ORACLE SQL性能优化系列(十三)

27. 基础表的选择 基础表(Driving Table)是指被最先访问的表(通常以全表扫描的方式被访问). 根据优化器的不同, SQL语句中基础表的选择是不一样的.如果你使用的是CBO (COST ...
  • hzfu007
  • hzfu007
  • 2006年09月13日 18:04
  • 685

ORACLE SQL性能优化系列 (十三)

 43. 用WHERE替代ORDER BY ORDER BY 子句只在两种严格的条件下使用索引. ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序. ORDER BY中所有的列...
  • hit040420224
  • hit040420224
  • 2008年12月05日 10:36
  • 202

ORACLE SQL性能优化系列 (十三) (十四) 完结篇

43.       用WHERE替代ORDER BYORDER BY 子句只在两种严格的条件下使用索引. ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.ORDER BY中所...
  • cwwhy
  • cwwhy
  • 2005年06月27日 13:08
  • 645

ORACLE SQL性能优化汇总

ORACLE SQL性能优化汇总:SQL语句共享、ORACLE SQL 多表联合查询、where语句条件顺序、ORACEL多表连接查询指定表别名alias等...
  • tianwei7518
  • tianwei7518
  • 2015年03月11日 23:41
  • 1017

高级SQL优化(二) ——《12年资深DBA教你Oracle开发与优化——性能优化部分》

充分利用索引 索引的限制 1. 索引对不等号和NOT的限制   如果WHERE条件中出现!=或者 Oracle 10g起,在基于CBO的优化器模式下Oralce会进行自动优...
  • holandstone
  • holandstone
  • 2016年05月21日 23:36
  • 2010

ORACLE SQL性能优化系列

 选择最有效率的表名顺序(只在基于规则的优化器中有效)        ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table...
  • meteorlWJ
  • meteorlWJ
  • 2008年06月16日 13:36
  • 534

ORACLE SQL性能优化系列

ORACLE SQL性能优化系列1. 选用适合的ORACLE优化器 ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本)c. CHOOSE (选择性) 设置缺省的...
  • xianbin
  • xianbin
  • 2006年11月19日 14:55
  • 782

ORACLE SQL性能优化No3--ORACLE SQL性能优化系列

1. 选用适合的ORACLE优化器      ORACLE的优化器共有3种:     a.  RULE (基于规则)   b. COST (基于成本)  c. CHOOSE (选择性)      设置...
  • elimago
  • elimago
  • 2007年07月02日 12:31
  • 788

Oracle查询性能优化(面试题:数据库查询优化也是常问的问题)

原则一:注意WHERE子句中的连接顺序:  ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WH...
  • hxpjava1
  • hxpjava1
  • 2017年02月21日 11:40
  • 1193

Oracle 数据库性能优化3日实战(企业培训)

课程名称一: Oracle性能优化及调整 课程时长 1天 课程深度: 高级 上机实验: 10%-30% 授课对象: Oracle开发人员、Oracle数据库管理人员,应用程序开发人员 课程描述...
  • robinson_0612
  • robinson_0612
  • 2017年04月05日 11:49
  • 2474
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ORACLE SQL性能优化系列 (十三)
举报原因:
原因补充:

(最多只允许输入30个字)