oracle sql性能1(四)

2014-11-24 16:43:45 · 作者: · 浏览: 3
ROM DEPT D WHERE D.DEPT_NO = E.DEPT_NO AND DEPT_CAT = ‘A’); 20用表连接替换EXISTS 通常来说 , 采用表连接的方式比EXISTS更有效率 SELECT ENAME FROM EMP E WHERE EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT_NO = E.DEPT_NO AND DEPT_CAT = ‘A’); (更高效) SELECT ENAME FROM DEPT D,EMP E WHERE E.DEPT_NO = D.DEPT_NO AND DEPT_CAT = ‘A’ ;

(译者按: 在RBO的情况下,前者的执行路径包括FILTER,后者使用NESTED LOOP)
21用EXISTS替换DISTINCT
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换
例如:
低效: 
     SELECT DISTINCT DEPT_NO,DEPT_NAME 
     FROM DEPT D,EMP E 
     WHERE D.DEPT_NO = E.DEPT_NO 
高效: 
     SELECT DEPT_NO,DEPT_NAME 
     FROM DEPT D 
     WHERE EXISTS ( SELECT ‘X’ 
                     FROM EMP E 
                     WHERE E.DEPT_NO = D.DEPT_NO); 

EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.
22识别’低效执行’的SQL语句
用下列SQL工具找出低效SQL:
  SELECT EXECUTIONS , DISK_READS, BUFFER_GETS, 
         ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio, 
         ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run, 
         SQL_TEXT 
FROM   V$SQLAREA 
WHERE  EXECUTIONS>0 
AND     BUFFER_GETS > 0  
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8  
ORDER BY 4 DESC; 

(译者按: 虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始终是一个最好的方法)
23使用TKPROF 工具来查询SQL性能状态
SQL trace 工具收集正在执行的SQL的性能状态数据并记录到一个跟踪文件中. 这个跟踪文件提供了许多有用的信息,例如解析次数.执行次数,CPU使用时间等.这些数据将可以用来优化你的系统.
设置SQL TRACE在会话级别: 有效
ALTER SESSION SET SQL_TRACE TRUE
设置SQL TRACE 在整个 数据库有效仿, 你必须将SQL_TRACE参数在init.ora中设为TRUE, USER_DUMP_DEST参数说明了生成跟踪文件的目录
(译者按: 这一节中,作者并没有提到TKPROF的用法, 对SQL TRACE的用法也不够准确, 设置SQL TRACE首先要在init.ora中设定TIMED_STATISTICS, 这样才能得到那些重要的时间状态. 生成的trace文件是不可读的,所以要用TKPROF工具对其进行转换,TKPROF有许多执行参数. 大家可以参考ORACLE手册来了解具体的配置. )
24用EXPLAIN PLAN 分析SQL语句
EXPLAIN PLAN 是一个很好的分析SQL语句的工具,它甚至可以在不执行SQL的情况下分析语句. 通过分析,我们就可以知道ORACLE是怎么样连接表,使用什么方式扫描表(索引扫描或全表扫描)以及使用到的索引名称.
你需要按照从里到外,从上到下的次序解读分析的结果. EXPLAIN PLAN分析的结果是用缩进的格式排列的, 最内部的操作将被最先解读, 如果两个操作处于同一层中,带有最小操作号的将被首先执行.
NESTED LOOP是少数不按照上述规则处理的操作, 正确的执行路径是检查对NESTED LOOP提供数据的操作,其中操作号最小的将被最先处理.
译者按:
通过实践, 感到还是用SQLPLUS中的SET TRACE 功能比较方便.
举例:
SQL> list 
   1  SELECT * 
   2  FROM dept, emp 
   3* WHERE emp.deptno = dept.deptno 
SQL> set autotrace traceonly /*traceonly 可以不显示执行结果*/ 
SQL> / 
14 rows selected. 
Execution Plan 
---------------------------------------------------------- 
    0      SELECT STATEMENT Optimizer=CHOOSE 
    1    0   NESTED LOOPS 
    2    1     TABLE ACCESS (FULL) OF 'EMP'  
    3    1     TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' 
    4    3       INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE) 
   
Statistics 
---------------------------------------------------------- 
           0  recursive calls 
           2  db block gets 
          30  consistent gets 
           0  physical reads 
           0  redo size 
        2598  bytes sent via SQL*Net to client 
         503  bytes received via SQL*Net from client 
           2  SQL*Net roundtrips to/from client 
           0  sorts (memory) 
           0  sorts (disk) 
          14  rows processed 

通过以上分析,可以得出实际的执行步骤是:
1TABLE ACCESS (FULL) OF 'EMP'  
2INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE) 
3TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' 
4NESTED LOOPS (JOINING 1 AND 3) 

注: 目前许多第三方的工具如TOAD和ORACLE本身提供的工具如OMS的SQL Analyze都提供了极其方便的EXPLAIN PLAN工具.也许喜欢图形化界面的朋友们可以选用它们.
25用索引提高效率
索引是表的一个概念部分,用来提高检索数据的效率. 实际上,ORACLE使用了一个复杂的自平衡B-tree结构. 通常,通过索引查询数据比全表扫描要快. 当ORACLE找出执行查询和Update语句的最佳路径时, ORACLE优化器将使用索引. 同样在联结多个表时使用索引也可以提高效率. 另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证.
除了那些LONG或LONG R