首页 > 代码库 > Oracle Sql语句优化

Oracle Sql语句优化

1.最高效的删除重复记录方法 (因为使用了ROWID)
  例子:
  DELETE FROM  EMP E  WHERE  E.ROWID > (SELECT MIN(X.ROWID) FROM  EMP X  WHERE  X.EMP_NO = E.EMP_NO);

2.在含有子查询的 SQL 语句中 , 要特别注意减少对表的查询
  例子:
  SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = (SELECT TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE  VERSION = 604)

3.用 EXISTS 替代 I N 、用 NOT EXISTS 替代 NOT IN :
  在许多基于基础表的查询中 , 为了满足一个条件 , 往往需要对另一个表进行联接 . 在这种情况下 , 使用EXISTS( 或 NOT EXISTS) 通常将提高查询的效率 . 在子查询中 ,NOT IN 子句将执行一个内部的排序和合并 .无论在哪种情况下 ,NOT IN 都是最低效的( 因为它对子查询中的表执行了一个全表遍历). 为了避免使用 NOT IN , 我们可以把 它改写成外连接 (Outer Joins) 或 NOT EXISTS.
  例子:
 (高效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X‘ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB‘)
  (低效) SELECT  * FROM  EMP (基础表) WHERE  EMPNO > 0 AND  DEPTNO IN (SELECT DEPTNO FROM  DEPT WHERE LOC =‘MELB‘ )

4.用 exists 替换 distinct :
  当提交一个包含一对多表信息 ( 比如部门表和雇员表 ) 的查询时 , 避免在 select 子句中使用 distinct.一般可以考虑用 exist 替换 , exists 使查询更为迅速 , 因为 rdbms 核心模块将在 子查询的条件一旦满足后, 立刻返回结果 .
  例子:
  ( 低效 ): 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 ) ;

5.sql 语句用大写的 ;因为 oracle 总是先解析 sql 语句,把小写的字母转换成大写的再执行

6.在 java 代码中尽量少用连接符“+”连接字符串!代替(单线程:StringBuild;多线程:StringBuffer)

7.避免在索引列上使用计算.
  WHERE 子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描.
  举例 :
  低效:
  SELECT … FROM  DEPT  WHERE SAL * 12 > 25000;
  高效 :
  SELECT … FROM DEPT WHERE SAL > 25000/12;

8.用 >= 替代 >
  高效 :
  SELECT * FROM  EMP  WHERE  DEPTNO >=4
  低效 :
  SELECT * FROM EMP WHERE DEPTNO >3
  两者的区别在于 , 前者 DBMS 将直接跳到第一个 DEPT 等于 4 的记录而后者将首先定位到 DEPTNO=3 的记录并且向前扫描到第一个 DEPT 大于 3 的记录 .

9.用 UNION ALL 替换 OR ( 适用于索引列 )
  通常情况下 , 用 UNION 替换 WHERE 子句中的 OR 将会起到较好的效果 . 对索引列使用 OR 将造成全表扫描.  注意 , 以上规则只针对多个索引列有效 . 如果有 column 没有被索引 , 查询效率可能会因为你没有选择 OR 而降低 . 在下面的例子中 , LOC_ID 和 REGION 上都建有索引 .
  高效 :
  SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10
  UNION
  SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE REGION = “MELBOURNE”
  低效 :
  SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
  如果你坚持要用 OR, 那就需要返回记录最少的索引列写在最前面

10.避免使用耗费资源的操作 :
  带有 DISTINCT,UNION,MINUS,INTERSECT,ORDER BY 的 SQL 语句会启动 SQL 引擎 执行耗费资源的排序 (SORT) 功能 . DISTINCT 需要一次排序操作 , 而其他的至少需要执行两次排序 . 通常 ,带有 UNION, MINUS , INTERSECT 的 SQL 语句都可以用其他方式重写 . 如果你的数据库的 SORT_AREA_SIZE调配得好 , 使用 UNION , MINUS, INTERSECT 也是可以考虑的 , 毕竟它们的可读性很强

11.避免在索引列上使用 NOT 通常 ,我们要避免在索引列上使用 NOT, NOT 会产生在和在索引列上使用函数相同的 影响 . 当 ORACLE” 遇到 ”NOT,他就会停止使用索引转而执行全表扫描 .