Oracle8i基于规则的优化机制对表达式的处理

oracle|优化

     ORACLE优化器在任何可能的时候都会对表达式进行评估,并且把特定的语法结构转换成等价的结构,这么做的原因是:
·         要么结果表达式能够比源表达式具有更快的速度

·         要么源表达式只是结果表达式的一个等价语义结构

不同的SQL结构有时具有同样的操作(例如:= ANY (subquery) and IN (subquery)),ORACLE会把他们映射到一个单一的语义结构。

下面将讨论优化器如何评估优化如下的情况和表达式:常量 LIKE 操作符 IN 操作符 ANY和SOME 操作符 ALL 操作符 BETWEEN 操作符 NOT 操作符 传递(Transitivity) 确定性(DETERMINISTIC)函数
常量
常量的计算是在语句被优化时一次性完成,而不是在每次执行时。下面是检索月薪大于2000的的表达式:

·         sal > 24000/12

·         sal > 2000

·         sal*12 > 24000

如果SQL语句包括第一种情况,优化器会简单地把它转变成第二种。 

注意:优化器不会简化跨越比较符的表达式,例如第三条语句,鉴于此,应用程序开发者应该尽量写用常量跟字段比较检索的表达式,而不要将字段置于表达式当中。
LIKE 操作符
优化器把使用LIKE操作符和一个没有通配符的表达式组成的检索表达式转换为一个“=”操作符表达式。

例如:优化器会把表达式ename LIKE 'SMITH'转换为ename = 'SMITH'

优化器只能转换涉及到可变长数据类型的表达式,前一个例子中,如果ENAME字段的类型是CHAR(10), 那么优化器将不做任何转换。
IN 操作符
优化器把使用IN比较符的检索表达式替换为等价的使用“=”和“OR”操作符的检索表达式。

例如,优化器会把表达式ename IN ('SMITH','KING','JONES')替换为

    ename = 'SMITH' OR ename = 'KING' OR ename = 'JONES'
ANY和SOME 操作符
优化器将跟随(following)值列表的ANY和SOME检索条件用等价的同等操作符和“OR”组成的表达式替换。

例如,优化器将如下所示的第一条语句用第二条语句替换:

·         sal > ANY (:first_sal, :second_sal)

·         sal > :first_sal OR sal > :second_sal

优化器将跟随子查询的ANY和SOME检索条件转换成由“EXISTS”和一个相应的子查询组成的检索表达式。

例如,优化器将如下所示的第一条语句用第二条语句替换:

·         x > ANY (SELECT sal FROM emp WHERE job = 'ANALYST')

·         EXISTS (SELECT sal FROM emp WHERE job = 'ANALYST' AND x > sal)
ALL 操作符
优化器将跟随值列表的ALL操作符用等价的“=”和“AND”组成的表达式替换。

例如,sal > ALL (:first_sal, :second_sal)表达式会被替换为:

    sal > :first_sal AND sal > :second_sal

 对于跟随子查询的ALL表达式,优化器用ANY和另外一个合适的比较符组成的表达式替换。

例如,优化器会把表达式 x > ALL (SELECT sal FROM emp WHERE deptno = 10) 替换为:

    NOT (x <= ANY (SELECT sal FROM emp WHERE deptno = 10))

接下来优化器会把第二个表达式适用ANY表达式的转换规则转换为下面的表达式:

    NOT EXISTS (SELECT sal FROM emp WHERE deptno = 10 AND x <= sal)
BETWEEN 操作符
优化器总是用“>=”和“<=”比较符来等价的代替BETWEEN操作符。

例如:优化器会把表达式sal BETWEEN 2000 AND 3000用sal >= 2000 AND sal <= 3000来代替。
NOT 操作符
优化器总是试图简化检索条件以消除“NOT”逻辑操作符的影响,这将涉及到“NOT”操作符的消除以及代以相应的比较运算符。

例如,优化器将下面的第一条语句用第二条语句代替:

·         NOT deptno = (SELECT deptno FROM emp WHERE ename = 'TAYLOR')

·         deptno <> (SELECT deptno FROM emp WHERE ename = 'TAYLOR')

通常情况下一个含有NOT操作符的语句有很多不同的写法,优化器的转换原则是使“NOT”操作符后边的子句尽可能的简单,即使可能会使结果表达式包含了更多的“NOT”操作符。

例如,优化器将如下所示的第一条语句用第二条语句代替:

·         NOT (sal < 1000 OR comm IS NULL)

·         NOT sal < 1000 AND comm IS NOT NULL sal >= 1000 AND comm IS NOT NULL
传递(Transitivity)
如果“WHERE”子句的两个检索条件涉及了一个共同的字段,优化器有时会根据传递原理推断出第三个检索条件,随后可以根据这个推断出的条件对语句进行优化,推断出的条件可能会激活一个原来的检索条件没有激活的潜在的接口路径(access path)。

注意:传递仅仅被用在基于代价(cost-based)的优化中。

假设有一个这样的包含两个检索条件的“WHERE”子句:WHERE 字段1 <comp_oper> 常量 AND字段1 = 字段2,在这个例子里,优化器会推断出新的检索条件:字段2 <comp_oper> 常量。在这里,<comp_oper>是比较运算符=、!=、^=、<>、>、<= 或 >=之中的任何一个,常量是指任何一个涉及了操作符、SQL函数、文字、绑定变量(bind variables)或者关联变量(correlation variables)的常量表达式。

例如,考虑这样一个包含两个各自使用了字段EMP.DEPTNO的检索条件的WHERE子句的查询:

SELECT * FROM emp, dept WHERE emp.deptno = 20 AND emp.deptno = dept.deptno;

使用传递优化,优化器会推断出如下条件:dept.deptno = 20

如果有索引存在于EMP.DEPTNO字段上,这个条件会使调用这个索引的接口路径有效。

注意:优化器只能对字段关联常量的表达式进行推断,而不是字段关联字段的表达式。例如,包含这样条件的WHERE子句:字段1 <comp_oper> 字段3 AND 字段1 = 字段2,这种情况不能推断出表达式:字段2 < comp_oper> 字段3。
确定性(DETERMINISTIC)函数
在某些情况下,优化器能够使用先前的函数返回结果而不是重新执行用户定义的函数,这仅仅对那些以限制的方式来执行的函数来说是有效的。这些函数必须对任何的输入都有同样的返回值,函数的结果必须不能因为包(PACKAGE)变量、数据库或会话(SESSION)的参数(例如NLS参数)不同而变化,如果函数在将来重新定义,返回值必须对任何参数来说仍然与以前的返回值相同。函数的创建者可以在以CREATE FUNCTION、CREATE PACKAGE或者CREATE TYPE声明函数时根据以上的要求使用DETERMINISTIC关键字向数据库申明该函数为确定性函数,数据库不会对确定性函数的合法性进行校验,即使一个函数明显的使用了包变量或操作了数据库,仍然可以被定义为确定性函数,这就是说如何安全合法的使用和定义确定性函数是程序员的责任。

当确定性函数在同一个查询里被多次调用,或者被基于函数的索引或物化视图(materialized view)调用时,有可能被一个已经计算出的值取代

时间: 2024-05-21 15:44:27

Oracle8i基于规则的优化机制对表达式的处理的相关文章

无法watch-当前方法的代码已经过优化 无法计算表达式的值

问题描述 当前方法的代码已经过优化 无法计算表达式的值 网上找的解决方案是在项目属性里不要勾选 代码优化 可是我的项目一直都没有勾选过 解决方案 你从哪看出来我使用了response.end 和 HttpContext.Current.ApplicationInstance.CompleteRequest 结束 ???? 解决方案二: 这种情况一般是使用了response.end,并将代码放在try catch里,解决办法就是将response.end去掉或正如楼主用HttpContext.Cu

Eclipse的字符串分区共享优化机制

在 Java/C# 这样基于引用语义处理字符串的语言中,作为不可变对象存在的字符串,如果内容相同,则可以通过某种机制实现重用.因为对这类语言来说,指向内存中两块内存位置不同内容相同的字符串,与同时指向一个字符串并没有任何区别.特别是对大量使用字符串的 XML 文件解析类似场合,这样的优化能够很大程度上降低程序的内存占用,如 SAX 解析引擎标准中就专门定义了一个 http://xml.org/sax/features/string-interning 特性用于字符串重用. 在语言层面,Java/

《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一2.5 执行计划中其他信息的含义

2.5 执行计划中其他信息的含义 通过DBMS_XPLAN输出执行计划,除了计划本身外,还可以获得一些其他信息帮助我们进一步分析执行计划及语句性能. 2.5.1 查询块和对象别名 在使用DBMS_XPLAN显示执行计划时,选择'ADVANCED'预定义格式作为参数或者加入'ALIAS'控制字符串,可以在输出中看到以下内容: Query Block Name / Object Alias (identified by operation id): -------------------------

优化器

Oracle 的优化器(Optimizer)实际上是数据库环境的参数设置.可以在INITsid.ORA 文件内的 OPTIMZER_MODE=RULE 或OPTIMZER_MODE=COST 或OPTIMZER_MODE=CHOOSE 来 设置优化目标.用户也可以在会话和查询方式下更改优化器的默认操作模式. 如果OPTIMZER_MODE=RULE,则激活基于规则的优化器(RBO).基于规则的优化器按照一 系列的语法规则来推测可能执行路径和比较可替换的执行路径. 如果OPTIMZER_MODE=

SQL语句优化提高数据库性能_MsSql

性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化.为了获得稳定的执行性能,SQL语句越简单越好.对复杂的SQL语句,要设法对之进行简化. 常见的简化规则如下: 1)不要有超过5个以上的表连接(JOIN) 2)考虑使用临时表或表变量存放中间结果 3)少用子查询 4)视图嵌套不要过深,一般视图嵌套不要超过2个为宜 一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出S

sql语句优化之SQL Server(详细整理)_MsSql

MS SQL Server查询优化方法 查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 5.网络速度慢 6.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7.锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8.sp_lock,sp_who,活动的用户查看,原因是读写竞争资源. 9.返回了不必要的行和列 10.查询语句不好,

oracle优化常用经典参考

2-调优步骤:   1 设计调优  2 应用调优 程序员代码 3 内存 4 连接 5 操作系统 2-已有产品的调优  1 定位问题  2 查看操作系统和oracle统计  3 考虑通用系统错误  4 假定问题  5 通过参数修改去调优   3调优方法  1 检查日志和trace  file  2 检查参数文件 3 检查 内存 cpu 4 那些sql占用cpu和io 如果相应时间慢;  1分析工作实现和相应时间 2 检查那部分时间长 3 细化问题     3 查看alert  log  1 查看位

SQL语句优化提高数据库性能

性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化.为了获得稳定的执行性能,SQL语句越简单越好.对复杂的SQL语句,要设法对之进行简化. 常见的简化规则如下: 1)不要有超过5个以上的表连接(JOIN) 2)考虑使用临时表或表变量存放中间结果 3)少用子查询 4)视图嵌套不要过深,一般视图嵌套不要超过2个为宜 一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出S

使你的 SQL 语句完全优化

我们要做到不但会写SQL,还要做到写出性能优良的SQL语句. (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. (2)WHERE子句中