ORACLE中where部分条件执行顺序测试
实验1:证明oracle SQL的语法分析应该是从右到左的
测试语句
--语句1
Select 'ok' From Dual Where 1 / 0 = 1 And 1 = 2;
--语句2
Select 'ok' From Dual Where 1 = 2 And 1 / 0 = 1;
10g环境下测试结果
如图所示,语句1不会报错,语句2报错
执行计划如下:
结论1:10g环境下的实验结果说明oracle SQL的语法分析应该是从右到左的
11g环境下测试结果
如图所示,语句1和语句2都没有报错
执行计划如下:
从两者的执行计划中可以看出plan hash value值相同,filter的过滤条件也相同,都使用了filter(NULL IS NOT NULL),这是优化器非常聪明的“短路”操作
结论2:由此可见在11g时oracle数据库对后除0操作做了特殊处理
实验2:证明了oracle SQL条件的执行是从右到左的
测试SQL
drop table temp;
create table temp( t1 varchar2(10),t2 varchar2(10));
insert into temp values('zm','abcde');
insert into temp values('sz','1');
insert into temp values('sz','2');
commit;
--语句1
select * from temp where to_number(t2)>1 and t1='sz';
--语句2
select * from temp where t1='sz' and to_number(t2)>1;
9i环境下测试结果
网络上有博文指出在9i上执行, 第1条语句执行不会出错,第2条语句会提示“无效的数字”,说明在9i上,SQL条件的执行确实是从右到左的,没有亲自验证。
10g环境下测试结果
11g环境下测试结果
实验3:证明同一个where子句中条件的先后顺序对效率影响不大
部分博文中提到ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,
那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.
测试语句
--语句1
SELECT *
FROM scott.EMP E
WHERE SAL > 1000
AND JOB = 'MANAGER'
AND 2 < (SELECT COUNT(*) FROM scott.EMP
WHERE MGR=E.EMPNO);
--语句2
SELECT *
FROM scott.EMP E
WHERE 2 < (SELECT COUNT(*) FROM scott.EMP
WHERE MGR=E.EMPNO)
and SAL > 1000
AND JOB = 'MANAGER';
10g环境下测试结果
两条语句在10g环境下的执行计划如下图
关于 Recursive Calls可以参考Oracle Recursive Calls说明
11g环境下测试结果
两条语句在11g环境下的执行计划如下图
两者的where条件顺序有差异,但是从执行计划中可以看出都是一致的。
结论3:11g环境下同一个where子句中条件的先后顺序对效率影响不大
参考文章链接:
Oracle中的where部分的各个条件的执行顺序