高效SQL语句必杀技
作者:网络转载 发布时间:[ 2013/6/18 10:28:10 ] 推荐标签:
5)整合简单,无关联的数据库访问
-->如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中以提高性能(即使它们之间没有关系)
-->整合前
SELECT name
FROM emp
WHERE empno = 1234;
SELECT name
FROM dept
WHERE deptno = 10;
SELECT name
FROM cat
WHERE cat_type = 'RD';
-->整合后
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';
-->从上面的SQL语句可以看出,尽管三条语句被整合为一条,性能得以提高,然可读性差,此时应权衡性能与代价
6) 删除重复记录
-->通过使用rowid来作为过滤条件,性能高效
DELETE FROM emp e
WHERE e.ROWID > (SELECT MIN( x.ROWID )
FROM emp x
WHERE x.empno = e.empno);
7)使用truncate 代替 delete
-->通常情况下,任意记录的删除需要在回滚段构造删除前镜像以实现回滚(rollback).对于未提交的数据在执行rollback之后,Oracle会生成
-->等价SQL语句去恢复记录(如delete,则生成对应的insert语句;如insert则生成对应的delete;如update,则是同时生成delete和insert
-->使用truncate命令则是执行DDL命令,不产生任何回滚信息,直接格式化并释放高水位线.故该语句性能高效.由于不能rollback,因此慎用。
8)尽量多使用COMMIT(COMMIT应确保事务的完整性)
-->只要有可能,在程序中尽量多使用COMMIT,这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少
-->COMMIT所释放的资源:
-->1.回滚段上用于恢复数据的信息
-->2.释放语句处理期间所持有的锁
-->3.释放redo log buffer占用的空间(commit将redo log buffer中的entries 写入到联机重做日志文件)
-->4.ORACLE为管理上述3种资源中的内部开销
9) 计算记录条数
-->一般的情况下,count(*)比count(1)稍快.如果可以通过索引检索,对索引列的计数是快的,因为直接扫描索引即可,例如COUNT(EMPNO)
-->实际情况是经测试上述三种情况并无明显差异。
10) 用Where子句替换HAVING子句
-->尽可能的避免having子句,因为HAVING 子句是对检索出所有记录之后再对结果集进行过滤。这个处理需要排序,总计等操作
-->通过WHERE子句则在分组之前即可过滤不必要的记录数目,从而减少聚合的开销
-->低效:
SELECT deptno, AVG( sal )
FROM emp
GROUP BY deptno
HAVING deptno = 20;
scott@CNMMBO> SELECT deptno, AVG( sal )
2 FROM emp
3 GROUP BY deptno
4 HAVING deptno= 20;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
583 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

sales@spasvo.com