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

原创 2001年09月05日 15:18:00
     ORACLE优化器在任何可能的时候都会对表达式进行评估,并且把特定的语法结构转换成等价的结构,这么做的原因是:

·         要么结果表达式能够比源表达式具有更快的速度

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

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

下面将讨论优化器如何评估优化如下的情况和表达式:常量 LIKE 操作符 IN 操作符 ANY和SOME 操作符 ALL 操作符 BETWEEN 操作符 NOT 操作符 传递(Transitivity) 确定性(DETERMINISTIC)函数

常量<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

常量的计算是在语句被优化时一次性完成,而不是在每次执行时。下面是检索月薪大于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)调用时,有可能被一个已经计算出的值取代

正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——5 DFA最小化

分类: C++ 算法 编译原理2013-07-18 23:39 421人阅读 评论(0) 收藏 举报 正则表达式编译原理DFA优化 目录(?)[+] 完整...
  • pi9nc
  • pi9nc
  • 2014年05月30日 09:20
  • 1422

基于支持向量机的结构风险最小化

基于统计学习理论的支持向量机算法研究 1   理论背景 基于数据的机器学习是现代智能技术中的重要方面,研究从观测数据(样本)出发寻找规律,利用这些规律对未来数据或无法观测的数据进行预测。迄今为...
  • dai_fun
  • dai_fun
  • 2015年10月14日 18:45
  • 2338

正则表达式DFA构造方法

陈梓瀚 vczh@163.com http://www.cppblog.com/vczh/ 1、问题概述 随着计算机语言的结构越来越复杂,为了开发优秀的编译器,人们已经渐渐感到将词法分析独...
  • Chinamming
  • Chinamming
  • 2013年12月06日 14:15
  • 11590

Oracle语句优化规则汇总(8)

1. 用UNION替换OR (适用于索引列)   通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果。 对索引列使用OR将造成全表扫描。注意, 以上规则只针对多个索引列有效。...
  • wbruce_leew
  • wbruce_leew
  • 2011年08月29日 10:15
  • 116

Oracle语句优化规则汇总(8)

1. 用UNION替换OR (适用于索引列)   通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果。 对索引列使用OR将造成全表扫描。注意, 以上规则只针对多个索引列有效。...
  • yywzgh
  • yywzgh
  • 2012年06月04日 23:43
  • 153

初看Java8新特性-Lambda表达式的语法规则

前言前面只是很零碎的举了一些有关Lambda表达式的例子,没有做一个系统的语法实例,这里将给出Lambda表达式的语法规则!语法规则无参数,无返回值程序实例: //无参数 无返回值 @T...
  • zjq_1314520
  • zjq_1314520
  • 2017年06月21日 14:03
  • 219

记一次ORACLE 8I standby增加数据文件操作

ORACLE 8I standby增加数据文件与10G后略有不同。 在10G及以后,DATAGUARD架构下在主库增加数据文件后,STANDBY_FILE_MANAGEMENT=AUTO时,备库会自...
  • q947817003
  • q947817003
  • 2015年10月30日 22:38
  • 696

oracle 8i升级 11G改字符集

以下内容经过测试,均可使用! 服务器A:Oracle8i,字符集:AMERICAN_AMERICA.US7ASCII,注册表nls_lang:AMERICAN_AMERICA.US7ASCI...
  • KakuroP
  • KakuroP
  • 2015年01月28日 10:55
  • 1107

Oracle8i Internal 封面&第一章

简介: 本书基于Oracle 8i和Oracle 8.1版本,包括了详细的,难以找寻到的关于Oracle 内部结构的信息(数据结构,算法,隐含参数,以及文档上未说明的系统统计信息)。 主要议题包括...
  • empoli
  • empoli
  • 2012年10月07日 13:40
  • 498

FME Object API Write to Oracle8i 空间表实例

FME Object API Write to Oracle8i 空间表实例 //FME Object API Write to Oracle8i 空间表实例 static void...
  • hsg77
  • hsg77
  • 2012年07月06日 14:52
  • 1159
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Oracle8i基于规则的优化机制对表达式的处理
举报原因:
原因补充:

(最多只允许输入30个字)