30个Oracle语句优化规则详解(四)

 
   | |

导读:本文主要介绍减少对表的查询、如何通过内部函数提高SQL效率、怎样使用使用表的别名(Alias)以及用NOT EXISTS替代NOT IN等方面的内容。

关键词:Oracle Oracle语句优化 表查询 表别名

正在加载数据...

15.减少对表的查询

在含有子查询的SQL语句中,要特别注意减少对表的查询。

例如:

低效


SELECT TAB_NAME
FROM TABLES
WHERE TAB_NAME = ( SELECT TAB_NAME
FROM TAB_COLUMNS
WHERE VERSION = 604)
AND DB_VER= ( SELECT DB_VER
FROM TAB_COLUMNS
WHERE VERSION = 604) 

高效


SELECT TAB_NAME
FROM TABLES
WHERE (TAB_NAME,DB_VER)
= ( SELECT TAB_NAME,DB_VER)
FROM TAB_COLUMNS
WHERE VERSION = 604)
Update 多个Column 例子:

低效:


UPDATE EMP
SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),
SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)
WHERE EMP_DEPT = 0020; 

高效:

UPDATE EMP
SET (EMP_CAT, SAL_RANGE)
= (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)
FROM EMP_CATEGORIES)
WHERE EMP_DEPT = 0020; 

16.通过内部函数提高SQL效率


SELECT H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC,COUNT(*)
FROM HISTORY_TYPE T,EMP E,EMP_HISTORY H
WHERE H.EMPNO = E.EMPNO
AND H.HIST_TYPE = T.HIST_TYPE
GROUP BY H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC; 

通过调用下面的函数可以提高效率。

FUNCTION LOOKUP_HIST_TYPE(TYP IN NUMBER) RETURN VARCHAR2
AS
TDESC VARCHAR2(30);
CURSOR C1 IS
SELECT TYPE_DESC
FROM HISTORY_TYPE
WHERE HIST_TYPE = TYP;
BEGIN
OPEN C1;
FETCH C1 INTO TDESC;
CLOSE C1;
RETURN (NVL(TDESC,’?’));
END;
FUNCTION LOOKUP_EMP(EMP IN NUMBER) RETURN VARCHAR2
AS
ENAME VARCHAR2(30);
CURSOR C1 IS
SELECT ENAME
FROM EMP
WHERE EMPNO=EMP;
BEGIN
OPEN C1;
FETCH C1 INTO ENAME;
CLOSE C1;
RETURN (NVL(ENAME,’?’));
END;
SELECT H.EMPNO,LOOKUP_EMP(H.EMPNO),
H.HIST_TYPE,LOOKUP_HIST_TYPE(H.HIST_TYPE),COUNT(*)
FROM EMP_HISTORY H
GROUP BY H.EMPNO , H.HIST_TYPE; 

(译者按:经常在论坛中看到如‘能不能用一个SQL写出…。’的贴子,殊不知复杂的SQL往往牺牲了执行效率。能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的)

17.使用表的别名(Alias)

当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上。这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。

(译者注:Column歧义指的是由于SQL中不同的表具有相同的Column名,当SQL语句中出现这个Column时,SQL解析器无法判断这个Column的归属)

18.用EXISTS替代IN

在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下,使用EXISTS(或NOT EXISTS)通常将提高查询的效率。

低效:


SELECT *
FROM EMP (基础表)
WHERE EMPNO > 0
AND DEPTNO IN (SELECT DEPTNO
FROM DEPT
WHERE LOC =‘MELB’) 

高效:


SELECT *
FROM EMP (基础表)
WHERE EMPNO > 0
AND EXISTS (SELECT‘X’
FROM DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
AND LOC =‘MELB’) 

(译者按:相对来说,用NOT EXISTS替换NOT IN将更显著地提高效率,下一节中将指出)

19.用NOT EXISTS替代NOT IN

在子查询中,NOT IN子句将执行一个内部的排序和合并。无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历)。为了避免使用NOT IN,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS。

例如:


SELECT …
FROM EMP
WHERE DEPT_NO NOT IN (SELECT DEPT_NO
FROM DEPT
WHERE DEPT_CAT=’A’); 

为了提高效率。改写为:

(方法一:高效)


SELECT ….
FROM EMP A,DEPT B
WHERE A.DEPT_NO = B.DEPT(+)
AND B.DEPT_NO IS NULL
AND B.DEPT_CAT(+) = ‘A’

(方法二:最高效)


SELECT ….
FROM EMP E
WHERE NOT EXISTS (SELECT ‘X’
FROM DEPT D
WHERE D.DEPT_NO = E.DEPT_NO
AND DEPT_CAT = ‘A’); 


30个Oracle语句优化规则详解
 30个Oracle语句优化规则详解(一)
 30个Oracle语句优化规则详解(二)
 30个Oracle语句优化规则详解(三)
 30个Oracle语句优化规则详解(四)
 30个Oracle语句优化规则详解(五)
 30个Oracle语句优化规则详解(六)

原文出处:http://tech.it168.com/lists/0243/0/0243.shtml
 
来源:IT168    作者: gjm008     
 
 
 
 
 

Oracle性能与调优

 
在关系型数据库理论中,在任何表中对行列的顺序并没有严格的概念。一个表就是一个数据集,而数据集是没有顺序而言的。
 
在进行Oracle升级过程中,创建测试用例来验证升级并没有对数据或者读取这个数据库的应用造成不良的影响是至关重要的。
 
去年年底当Oracle公司宣布他们的虚拟管理软件Oracle VM时,该公司承诺Oracle应用程序能顺利地被虚拟化,而同时Oracle公司对公众声称它不支持虚拟化系统,不能在……

热门技术手册排行

 

在本次的技术手册中,我们为您提供了PL/SQL的基础知识以及专家指导,包括了PL/SQL中的数据类型简介、PL/SQL函数与触发器以及PL/SQL中的存储过程等,相信您无论是高手还是菜鸟都可以获得有帮助的信息。

 

本系列文章由三部分组成,为Oracle数据库管理员(DBA)面试成功的必备手册。本专题内容囊括从DBA最初的面试开始,从写“杀手简历”到求职信、到面试过程到Oracle认证再到上升到公司高层最后到你成为公司里的明星DBA。专家为你一一指点迷津,最终让你登上成功的宝座。

 

要成为一名DBA,你需要具备哪些素质?DBA的薪酬待遇如何?DBA的职业道路究竟可以走向何方?我们将在本次的技术手册中为您一一解答。

 

在本次技术手册中,我们将对SQL Server存储过程的调试进行详细的介绍,包括了基础的调试方法和在调试过程中出现的T-SQL性能问题和解决方法。

 

本技术专题主要围绕sql server设计这个话题展开,侧重介绍了sql server集簇索引的设计、如何创建sql server索引、如何优化索引、索引的能与不能、处理sql server 2000索引碎片技巧以及维护sql server索引以实现查询优化等等。

查看更多
 
 

登录TechTarget中国

关闭
本服务仅向TechTarget中国的会员开放,请登录或立即免费注册
电子邮件地址:
请输入您的电子邮件地址
密码:
下次自动登录