写出高性能 SQL 语句的 35 条方法
(1)整合简单,无关联的数据库访问:
如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)
(2)删除重复记录:
最高效的删除重复记录方法( 因为使用了 ROWID)例子:
DELETEFROMEMP EWHEREE.ROWID > (SELECT MIN(X.ROWID)
FROMEMP XWHEREX.EMP_NO = E.EMP_NO);
(3)用 TRUNCATE 替代 DELETE:
当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你
没有 COMMIT 事务,ORACLE 会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状
况) 而当运用 TRUNCATE 时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很
少的资源被调用,执行时间也会很短. (译者按: TRUNCATE 只在删除全表适用,TRUNCATE 是 DDL 不是
DML)
(4)选择最有效率的表名顺序(只在基于规则的优化器中有效):
ORACLE 的解析器按照从右到左的顺序处理 FROM 子句中的表名,FROM 子句中写在最后的表(基础表
driving table)将被最先处理,在 FROM 子句中包含多个表的情况下,你必须选择记录条数最少的表作为
基础表。如果有 3 个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是
指那个被其他表所引用的表.
(5)WHERE 子句中的连接顺序.:
ORACLE 采用自下而上的顺序解析 WHERE 子句,根据这个原理,表之间的连接必须写在其他 WHERE 条件
之前, 那些可以过滤掉最大数量记录的条件必须写在 WHERE 子句的末尾.
(6)SELECT 子句中避免使用‘* ‘:
ORACLE 在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味
着将耗费更多的时间
(7)减少访问数据库的次数:
ORACLE 在内部执行了许多工作: 解析 SQL 语句, 估算索引的利用率, 绑定变量, 读数据块等;
(8)在 SQL*Plus , SQL*Forms 和 Pro*C 中重新设置 ARRAYSIZE 参数, 可以增加每次数据库访问的检
索数据量,建议值为 200
(9)使用 DECODE 函数来减少处理时间:
使用 DECODE 函数可以避免重复扫描相同记录或重复连接相同的表.
(11)用 Where 子句替换 HAVING 子句:
避免使用 HAVING 子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,
总 计 等 操 作 . 如 果 能 通 过 WHERE 子 句 限 制 记 录 的 数 目 , 那 就 能 减 少 这 方 面 的 开 销 . ( 非 oracle
中)on、where、having 这三个都可以加条件的子句中,on 是最先执行,where 次之,having 最后,
因为 on 是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该
速度是最快的,where 也应该比 having 快点的,因为它过滤数据后才进行 sum,在两个表联接时才用
on 的,所以在一个表的时候,就剩下 where 跟 having 比较了。在这单表查询统计的情况下,如果要过
滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是 where 可以使用 rushmore 技术,而
having 就不能,在速度上后者要慢如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不
确定的,根据上篇写的工作流程,where 的作用时间是在计算之前就完成的,而 having 就是在计算后才