oracle语句优化规则详解

上传人:小** 文档编号:46747375 上传时间:2018-06-27 格式:DOC 页数:15 大小:48KB
返回 下载 相关 举报
oracle语句优化规则详解_第1页
第1页 / 共15页
oracle语句优化规则详解_第2页
第2页 / 共15页
oracle语句优化规则详解_第3页
第3页 / 共15页
oracle语句优化规则详解_第4页
第4页 / 共15页
oracle语句优化规则详解_第5页
第5页 / 共15页
点击查看更多>>
资源描述

《oracle语句优化规则详解》由会员分享,可在线阅读,更多相关《oracle语句优化规则详解(15页珍藏版)》请在金锄头文库上搜索。

1、Oracle 语句优化规则详解语句优化规则详解1.选用适合的 Oracle 优化器 Oracle 的优化器共有 3 种: a.RULE(基于规则) b.COST(基于成本) c.CHOOSE(选择性) 设置缺省的优化器,可以通过对 init.ora 文件中 OPTIMIZER_MODE 参数的各种声 明,如 RULE、COST、CHOOSE、ALL_ROWS、FIRST_ROWS。你当然也在 S QL 句级或是会话(session)级对其进行覆盖。 为了使用基于成本的优化器(CBO,Cost-Based Optimizer),你必须经常运行 anal yze 命令,以增加数据库中的对象统计信息

2、(object statistics)的准确性。 如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是 否运行过 analyze 命令有关。如果 table 已经被 analyze 过,优化器模式将自动成 为 CBO,反之,数据库将采用 RULE 形式的优化器。 在缺省情况下,Oracle 采用 CHOOSE 优化器,为了避免那些不必要的全表扫描(f ull table scan),你必须尽量避免使用 CHOOSE 优化器,而直接采用基于规则或 者基于成本的优化器。 2.访问 Table 的方式 Oracle 采用两种访问表中记录的方式: a.全表扫描 全表扫描就是顺

3、序地访问表中每条记录。Oracle 采用一次读入多个数据块(databas e block)的方式优化全表扫描。 b. 通过 ROWID 访问表 你可以采用基于 ROWID 的访问方式情况,提高访问表的效率,ROWID 包含了表 中记录的物理位置信息Oracle 采用索引(INDEX)实现了数据和存放数据的物理 位置(ROWID)之间的联系。通常索引提供了快速访问 ROWID 的方法,因此那些基 于索引列的查询就可以得到性能上的提高。 3.共享 SQL 语句 为了不重复解析相同的 SQL 语句,在第一次解析之后,Oracle 将 SQL 语句存放在内存中。这块位于系统全局区域 SGA(syst

4、em global area)的共享池(shared bu ffer pool)中的内存可以被所有的数据库用户共享。因此,当你执行一个 SQL 语句( 有时被称为一个游标)时,如果它和之前的执行过的语句完全相同,Oracle 就能很 快获得已经被解析的语句以及最好的执行路径。Oracle 的这个功能大大地提高了 S QL 的执行性能并节省了内存的使用。 可惜的是 Oracle 只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适 用于多表连接查询。 数据库管理员必须在 init.ora 中为这个区域设置合适的参数,当这个内存区域越大 ,就可以保留更多的语句,当然被共享的

5、可能性也就越大了。 当你向 Oracle 提交一个 SQL 语句,Oracle 会首先在这块内存中查找相同的语句 。 这里需要注明的是,Oracle 对两者采取的是一种严格匹配,要达成共享,SQL 语 句必须完全相同(包括空格,换行等)。 共享的语句必须满足三个条件: A.字符级的比较: 当前被执行的语句和共享池中的语句必须完全相同。 例如: SELECT * FROM EMP; 和下列每一个都不同 SELECT * from EMP; Select * From Emp; SELECT * FROM EMP; B.两个语句所指的对象必须完全相同: 例如: 用户对象名如何访问 Jack sal

6、_limit private synonym Work_city public synonym Plant_detail public synonym Jill sal_limit private synonym Work_city public synonym Plant_detail table owner 考虑一下下列 SQL 语句能否在这两个用户之间共享。 SQL 能否共享原因 select max(sal_cap) from sal_limit;不能每个用户都有一个 private synonym - sal_limit,它们是不同的对象 select count(*0 from w

7、ork_city where sdesc like NEW%;能两个用户访问相 同的对象 public synonym - work_city select a.sdesc,b.location from work_city a,plant_detail b where a.city_id = b.city_id 不能用户 jack 通过 private synonym 访问 plant_detail 而 jill 是表的所有 者,对象不同。 C.两个 SQL 语句中必须使用相同的名字的绑定变量(bind variables) 例如:第一组的两个 SQL 语句是相同的(可以共享),而第二组中的

8、两个语句是不 同的(即使在运行时,赋于不同的绑定变量相同的值) a. select pin ,name from people where pin = :blk1.pin; select pin ,na me from people where pin = :blk1.pin; b. select pin ,name from people where pin = :blk1.ot_ind; select pin ,name from people where pin = :bl k1.ov_ind; 4.选择最有效率的表名顺序(只在基于规则的优化器中有效) Oracle 的解析器按照从右到左

9、的顺序处理 FROM 子句中的表名,因此 FROM 子句 中写在最后的表(基础表 driving table)将被最先处理。在 FROM 子句中包含多个 表的情况下,你必须选择记录条数最少的表作为基础表。当 Oracle 处理多个表时 ,会运用排序及合并的方式连接它们。首先,扫描第一个表(FROM 子句中最后的 那个表)并对记录进行派序,然后扫描第二个表(FROM 子句中最后第二个表),最 后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并。 例如: 表 TAB1 16,384 条记录 表 TAB2 1 条记录 选择 TAB2 作为基础表(最好的方法) select count(*)

10、 from tab1,tab2 执行时间 0.96 秒 选择 TAB2 作为基础表(不佳的方法) select count(*) from tab2,tab1 执行时间 26.09 秒 如果有 3 个以上的表连接查询,那就需要选择交叉表(intersection table)作为基础 表,交叉表是指那个被其他表所引用的表。 例如:EMP 表描述了 LOCATION 表和 CATEGORY 表的交集。 SELECT * FROM LOCATION L , CATEGORY C, EMP E WHERE E.EMP_ NO BETWEEN 1000 AND 2000 AND E.CAT_NO =

11、C.CAT_NO AND E.LOC N = L.LOCN 将比下列 SQL 更有效率 SELECT * FROM EMP E , LOCATION L , CATEGORY C WHERE E.CAT_ NO = C.CAT_NO AND E.LOCN = L.LOCN AND E.EMP_NO BETWEEN 100 0 AND 2000 5. WHERE 子句中的连接顺序 Oracle 采用自下而上的顺序解析 WHERE 子句,根据这个原理,表之间的连接必 须写在其他 WHERE 条件之前,那些可以过滤掉最大数量记录的条件必须写在 W HERE 子句的末尾。 例如: (低效,执行时间 1

12、56.3 秒) SELECT FROM EMP E WHERE SAL 50000 AND JOB = MANAGER AND 25 50000 AND JOB = MANAGER; 6.SELECT 子句中避免使用 * 当你想在 SELECT 子句中列出所有的 COLUMN 时,使用动态 SQL 列引用*是一 个方便的方法。不幸的是,这是一个非常低效的方法。实际上,Oracle 在解析的 过程中,会将*依次转换成所有的列名,这个工作是通过查询数据字典完成的,这 意味着将耗费更多的时间。 7.减少访问数据库的次数 当执行每条 SQL 语句时,Oracle 在内部执行了许多工作:解析 SQL 语

13、句,估算 索引的利用率,绑定变量,读数据块等等。由此可见,减少访问数据库的次数,就 能实际上减少 Oracle 的工作量。 例如,以下有三种方法可以检索出雇员号等于 0342 或 0291 的职员。 方法 1(最低效) SELECT EMP_NAME, SALARY, GRADE FROM EMP WHERE EMP_NO = 342; SELECT EMP_NAME, SALARY, GRADE FROM EMP WHERE EMP_N O = 291; 方法 2(次低效) DECLARE CURSOR C1 (E_NO NUMBER) IS SELECT EMP_NAME,SALAR Y,

14、GRADE FROM EMP WHERE EMP_NO = E_NO; BEGIN OPEN C1(342); FETCH C1 INTO ,.,. ; OPEN C1(291); FETCH C1 INTO ,.,. ; CLOSE C1; END; 方法 3(高效) SELECT A.EMP_NAME,A.SALARY,A.GRADE, B.EMP_NAME, B.SALARY, B. GRADE FROM EMP A,EMP B WHERE A.EMP_NO = 342 AND B.EMP_NO = 291; 注意: 在 SQL*Plus,SQL*Forms 和 Pro*C 中重新设置

15、ARRAYSIZE 参数,可以增加每 次数据库访问的检索数据量,建议值为 200。 8.使用 DECODE 函数来减少处理时间 使用 DECODE 函数可以避免重复扫描相同记录或重复连接相同的表。 例如: SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0020 A ND ENAME LIKESMITH%; SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKESMITH%; 你可以用 DECODE 函数高效地得到相同结果 SELECT COUNT(DECOD

16、E(DEPT_NO,0020,X,NULL) D0020_COUNT, COU NT(DECODE(DEPT_NO,0030,X,NULL) D0030_COUNT, SUM(DECODE(DEP T_NO,0020,SAL,NULL) D0020_SAL, SUM(DECODE(DEPT_NO,0030,SAL,NU LL) D0030_SAL FROM EMP WHERE ENAME LIKESMITH%; 类似的,DECODE 函数也可以运用于 GROUP BY 和 ORDER BY 子句中。 9.整合简单,无关联的数据库访问 如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们 之间没有关系) 例如: SELECT NAME FROM EMP WHERE EMP_NO = 1234; SELECT NAME FR OM DPT WHERE DPT_NO = 10 ; SELECT NAME FROM CAT WHERE C AT_TYPE =RD;

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 宣传企划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号