ORACLE SQL 优化1

--EXISTS 代替DISTINCT
SELECT DISTINCT D.DEPTNO,D.DNAME
    FROM DEPT D,EMP E
    WHERE D.DEPTNO = E.DEPTNO--0.078




    SELECT D.DEPTNO,D.DNAME
    FROM DEPT D
    WHERE EXISTS ( SELECT 'X'
                    FROM EMP E
                    WHERE E.DEPTNO = D.DEPTNO);--0.016
--UNION ALL 代替  UNION
--避免在索引列商使用函数,WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描。
--避免使用前置通配符,索引列所对应的值的第一个字符由通配符开始,索引将不被采用,将使用全表扫描
--避免在索引列商使用NOT,执行全表扫描
--避免在索引列商使用IS NLLL 和IS NOT NULL
/*因为空值不存在于索引列中,所以WHERE子句中对索引列进行
空值比较将使ORACLE停用该索引.


任何在where子句中使用is null或is not null的语句优化器是
不允许使用索引的。
*/
--避免出现索引列自动转换,因为内部发生的类型转换, 这个索引将不会被用到!
--在查询时尽量少用格式转换
--减少访问数据库的次数
--使用DECODE减少处理时间
SELECT COUNT(*),SUM(SAL)
   FROM EMP
   WHERE DEPTNO = 0020
   AND ENAME LIKE 'SMITH%';
   SELECT COUNT(*),SUM(SAL)
   FROM EMP
   WHERE DEPTNO = 0030
   AND ENAME LIKE 'SMITH%';


--你可以用DECODE函数高效地得到相同结果


SELECT COUNT(DECODE(DEPTNO,0020,'X',NULL)) D0020_COUNT,
        COUNT(DECODE(DEPTNO,0030,'X',NULL)) D0030_COUNT,
        SUM(DECODE(DEPTNO,0020,SAL,NULL)) D0020_SAL,
        SUM(DECODE(DEPTNO,0030,SAL,NULL)) D0030_SAL
FROM EMP WHERE ENAME LIKE 'SMITH%';
--减少对标的查询,在含有子查询的SQL语句中,要特别注意减少对表的查询.
--WHERE子句中的连接顺序
select * from emp e,dept d 
where d.deptno >10 and e.deptno =30 ; --0.031


--如果dept表返回的记录数较多的话,上面的查询语句会比下面的查询语句响应快得多。
select * from emp e,dept d 
where e.deptno =30 and d.deptno >10 ;--0.015
  
--WHERE 子句--函数、表达式使用
/*
最好不要在WHERE子句中使用函或表达式,如果要使用的话,最好统一使用相同的表达式或函数,这样便于以后使用合理的索引
*/
--ORDER BY 子句
/*
任何在Order by语句的非索引项或者有计算表达式都将降低查询速度
解决这个问题的办法就是重写order by语句以使用索引,也可以为所使用的列建立另外一个索引,同时应绝对避免在order by子句中使用表达式。
\
*/


--联接列
--对于有联接的列,即使最后的联接值为一个静态值,优化器是不会使用索引的。 
--带通配符的LIKE语句
--%在词首时,不使用索引,在字符串其他位置是可以使用索引的
--WHERE 子句替换HAVING子句
/*
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果
集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限
制记录的数目,那就能减少这方面的开销.
*/
--用NOT EXISTS 代替NOT IN子句
/*
在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况
下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历).  
使用NOT EXISTS 子句可以有效地利用索引。尽可能使用NOT EXISTS
来代替NOT IN,尽管二者都使用了NOT(不能使用索引而降低速度),
NOT EXISTS要比NOT IN查询效率更高。
*/
SELECT dname, deptno FROM dept WHERE 
deptno NOT IN (SELECT deptno FROM emp); --0.063




SELECT dname, deptno FROM dept WHERE 
NOT EXISTS 
    (SELECT deptno FROM emp WHERE dept.deptno = emp.deptno); --0.031
--索引提高效率,定期的重构索引是有必要的。
--避免在索引列上使用计算
/*
WHERE子句中,如果索引列是函数的一部分.优化器将不
使用索引而使用全表扫描.
*/
SELECT * FROM  emp  WHERE SAL * 12 > 25000; --0.031


SELECT * FROM emp WHERE SAL > 25000/12;--0.031
  --用>= 代替>
  --通过使用>=,<=等,避免使用NOT命令
  --如果由其他方法,不要使用子查询
  --外部联接“+”的用法
  --尽量多使用COMMIT
  /*
  COMMIT所释放的资源:
 回滚段上用于恢复数据的信息.
 被程序语句获得的锁
 redo log buffer 中的空间
 ORACLE为管理上述3种资源中的内部花费
  */
  --truncate 代替DELETE
  /*
  回滚段不再存放任何可被恢复的
信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,
执行时间也会很短.
  */
  --计算记录条数COUNT(列名)>count(*)>count(1)
  --字符型字段加引号
  --优化EXPORT和IMPORT,较大的BUFFER可以提高速度
  

你可能感兴趣的:(ORACLE SQL 优化1)