(1) 语句解析时的执行顺序
创建测试用的 函数create or replace function F1(v_in in varchar2) return varchar2 IS v_out varchar2(20);begin v_out := v_in; dbms_output.put_line('exec F1'); return v_out;end; create or replace function F2(v_in in varchar2) return varchar2 IS v_out varchar2(20);begin v_out := v_in; dbms_output.put_line('exec F2'); return v_out;end;执行select 1 from dual where F1('1')=1 and F2('1')='1';输出exec F2exec F1执行select 1 from dual where F2('1')=1 and F1('1')='1';输出exec F1exec F2(2)语句执行时的执行顺序创建测试用的表及初始记录drop table temp; create table temp( t1 varchar2(10),t2 varchar2(10)); insert into temp values('sz','1'); insert into temp values('sz','2'); insert into temp values('se','abcde');执行1
select * from temp where t1=('sz' || F1('')) and t2=('abcde'||F2(''));输出exec F1exec F2exec F1exec F2exec F1执行2
select * from temp where t2=('abcde'||F2('')) and t1=('sz' || F1(''));输出exec F2exec F2exec F2exec F1以上得出 执行1 先输出exec F1 所以是先使用 t1条件,而执行2 先使用t2条件
如果 通过统计信息来 按 过滤出记录少的条件先执行,则应该是先执行t2,因为t2只过滤出1条记录。此例中 没有建索引, 没有统计信息,查询优化器没有可利用的统计信息来优化条件的执行顺序。至于 oracle 中提到的CBO模式下动态采样 何时介入还不是很理解。 动态采样比如:对一次执行SQL时发现涉及对象(表、索引等)没有被分析、统计过,那么ORACLE会采用一种叫做动态采样的技术,动态的收集表和索引上的一些数据信息,来帮助oracle做出最优的选择
注:使用的是oracle 11g CBO优化器
要做深入分析 还需要加入表,索引,记录数的比较等多种情况,这些情况才是项目中真正会遇到和需要解决的,后续有机会补充。。。