首页 > 代码库 > 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,他就会停止使用索引转而执行全表扫描 .