前事不忘,后事之师,不忘国耻!

 注册  找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1862|回复: 0

Oracle语句优化规则汇总(2)

[复制链接]

Oracle语句优化规则汇总(2)

[复制链接]
ehxz

主题

0

回帖

7157

积分

管理员

积分
7157
2008-2-20 09:43:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
  1. WHERE子句中的连接顺序。
  ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。
  例如:
  (低效,执行时间156.3秒)
  SELECT …
  FROM EMP E
  WHERE SAL > 50000
  AND JOB = ‘MANAGER’
  AND 25 < (SELECT COUNT(*) FROM EMP
  WHERE MGR=E.EMPNO);

  (高效,执行时间10.6秒)
  SELECT …
  FROM EMP E
  WHERE 25 < (SELECT COUNT(*) FROM EMP
  WHERE MGR=E.EMPNO)
  AND SAL > 50000
  AND JOB = ‘MANAGER’;

  2. SELECT子句中避免使用 ‘ * ’
  当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法。不幸的是,这是一个非常低效的方法。 实际上,ORACLE在解析的过程中, 会将‘*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。
  3. 减少访问数据库的次数
  当执行每条SQL语句时, ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等。 由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作量。
  例如,以下有三种方法可以检索出雇员号等于0342或0291的职员。
  方法1 (最低效)
  
  SELECT EMP_NAME , SALARY , GRADE
  FROM EMP
  WHERE EMP_NO = 342;
  SELECT EMP_NAME , SALARY , GRADE
  FROM EMP
  WHERE EMP_NO = 291;

  
  方法2 (次低效)
  
  DECLARE
  CURSOR C1 (E_NO NUMBER) IS
  SELECT EMP_NAME,SALARY,GRADE
  FROM EMP
  WHERE EMP_NO = E_NO;
  BEGIN
  OPEN C1(342);
  FETCH C1 INTO …,..,.. ;
  OPEN C1(291);
  FETCH C1 INTO …,..,.. ;
  CLOSE C1;
  END;

  
  方法3 (高效)
  
  以下是引用片段:
  SELECT A.EMP_NAME , A.SALARY , A.GRADE,
  B.EMP_NAME , B.SALARY , B.GRADE
  FROM EMP A,EMP B
  WHERE A.EMP_NO = 342
  AND B.EMP_NO = 291;

  
  注意:
  在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200.
  4. 使用DECODE函数来减少处理时间
  使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。
  例如:
  
  SELECT COUNT(*),SUM(SAL)
  FROM EMP
  WHERE DEPT_NO = 0020
  AND ENAME LIKE ‘SMITH%’;
  SELECT COUNT(*),SUM(SAL)
  FROM EMP
  WHERE DEPT_NO = 0030
  AND ENAME LIKE ‘SMITH%’;

  你可以用DECODE函数高效地得到相同结果
  
  SELECT COUNT(DECODE(DEPT_NO,0020,’X’,NULL)) D0020_COUNT,
  COUNT(DECODE(DEPT_NO,0030,’X’,NULL)) D0030_COUNT,
  SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,
  SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL
  FROM EMP WHERE ENAME LIKE ‘SMITH%’;

  
  类似的,DECODE函数也可以运用于GROUP BY 和ORDER BY子句中。
  5. 整合简单,无关联的数据库访问
  如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)
  例如:
  
  SELECT NAME
  FROM EMP
  WHERE EMP_NO = 1234;
  SELECT NAME
  FROM DPT
  WHERE DPT_NO = 10 ;
  SELECT NAME
  FROM CAT
  WHERE CAT_TYPE = ‘RD’;

  
  上面的3个查询可以被合并成一个:
  
  SELECT E.NAME , D.NAME , C.NAME
  FROM CAT C , DPT D , EMP E,DUAL X
  WHERE NVL(‘X’,X.DUMMY) = NVL(‘X’,E.ROWID(+))
  AND NVL(‘X’,X.DUMMY) = NVL(‘X’,D.ROWID(+))
  AND NVL(‘X’,X.DUMMY) = NVL(‘X’,C.ROWID(+))
  AND E.EMP_NO(+) = 1234
  AND D.DEPT_NO(+) = 10
  AND C.CAT_TYPE(+) = ‘RD’;

  
  (虽然采取这种方法,效率得到提高,但是程序的可读性大大降低,所以还是要权衡之间的利弊)
免责申明1、欢迎访问本站,本文内容及相关资源来源于网络,版权归版权方所有!本站原创内容版权归本站所有,请勿转载!
2、本文内容仅代表作者观点,不代表本站立场,作者自负,本站资源仅供学习研究,请勿非法使用,否则后果自负!请下载后24小时内删除!
3、本文内容,包括但不限于源码、文字、图片等,仅供参考。本站不对其安全性,正确性等作出保证。但本站会尽量审核会员发表的内容。
4、如本帖侵犯到任何版权问题,请立即告知本站 ,本站将及时删除并致以最深的歉意!客服邮箱:admin@dbabbs.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|DBA论坛中国 ( 鲁ICP备20017503号-2 )

GMT+8, 2024-5-6 16:05 , Processed in 0.265383 second(s), 10 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表