SQL 语句 Where 子句项的执行次序问题

问:在下面的查询中, WHERE 语句的哪一部分先执行?

<script src="http://www.pcdog.com/tech/js/Ads.js" type="text/javascript"></script>

Select field names from emp, dept

where emp.dept_num = dept.num and

emp.name Like 'S%' and dept.name='IT';

答:执行次序随已有的索引、统计、和 session/init.ora 参数的不同而变化。

假定已有一个建立在 DEPT ( name )和 EMP ( dept_num )上的索引。假定优化器认为 DEPT 是唯一的,它可能按下面的顺序进行操作:

利用建立在 DEPT ( name )上的索引查找 dept 列

利用建立在 EMP ( dept_num )上的索引查找匹配的 emp 列(即连接 emp.dept_num = dept.num )

依据建立在 emp.ename like 'S%' 进行过滤

现在,我们假定没有建立在 EMP ( dept_num )上的索引,也没有建立在 DEPT ( name )上的索引,而存在建立在 EMP ( name )和 DEPT ( num )上的索引。优化器可能按下面的次序进行操作:

利用建立在 EMP ( name )上的索引找到带有 S 的 EMPS

利用建立在 DEPT ( num )上的索引找到匹配项

根据 dept.name = 'IT' 过滤结果

谓词求值的次序是不确定的,可以随时间的改变而改变,并由优化器决定。不要假定任何事情会按一定的次序发生。如果你那么做,随着时间的推移,你的应用程序可能会出现一些看起来非常奇怪的错误。看以下的例子:建立一个表,输入一些数据。当 X='a '时,第二列的数据“ Y ”是一个数值,当 X='b '时,“ Y ”不是数字。

SQL> create table t ( x varchar2(1), y varchar2(1) );

Table created.

SQL> insert into t values ( 'a', '1' );

1 row created.

SQL> insert into t values ( 'b', 'x' );

1 row created.

现在根据这个表运行一个查询:查找满足 x='a' , y=1 的行。

SQL> select * from t where x = 'a' and

y = 1;

ERROR:

ORA-01722: invalid number

no rows selected (错误,无效的数字,没有选择任何行)

呦,没有成功。在这种情况下,数据库首先执行 Y=1 ,当找到 Y='X' 的行后,很显然,它不能将 'X' 转换为一个数字,所以失败了。而下面的程序将给出不同的结果:

SQL> analyze table t compute statistics;

Table analyzed. (表已经分析过)

SQL> select * from t where x = 'a' and

y = 1;

X Y

- -

a 1

使用不同的优化器模式,成功了!为什么?优化器说:“嘿,检查 x= 'a' 要比检查 y=1 来得快,因为在 y=1 中有一个将 y 从字符变为数字的转换。所以,我先检查 x= 'a' ,然后再检查 y=1 。”

这个例子说明谓词执行的次序可能是不确定的,你不能指望有一种特定的执行次序。也就是说,当你依靠一个隐含的转换时,必须非常谨慎。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值