** 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 ** ** 手册来了解具体的配置 . ) **