此文章主要描述的是Oracle SQL條件的實際順序對相關性能的影響。在實際操作中有人會問到關於Oracle數據庫中的Where子句的條件書寫順序的正確與否是否會對SQL性能有影響,我的直覺是沒有影響。
因為如果這個順序有影響,Oracle應該早就能夠做到自動優化,但一直沒有關於這方面的確鑿證據。在網上查到的文章,一般認為在RBO優化器模式下無影響(10G開始,缺省為RBO優化器模式),而在CBO優化器模式下有影響,主要有兩種觀點:
a.能使結果最少的條件放在最右邊,SQL執行是按從右到左進行結果集的篩選的;
b.有人試驗表明,能使結果最少的條件放在最左邊,SQL性能更高。
查過oracle8到11G的在線文檔,關於SQL優化相關章節,沒有任何文檔說過where子句中的條件對SQL性能有影響,到底哪種觀點是對的,沒有一種確切的結論,只好自己來做實驗證明。結果表明,我們大家都知道Oracle SQL條件的相關執行是從右到左的,但條件的順序對SQL性能沒有影響。
實驗一:證明了SQL的語法分析是從右到左的
下面的試驗在9i和10G都可以得到相同的結果: 第1條語句執行不會出錯,第2條語句會提示除數不能為零。
- Select 'ok' From Dual Where 1 / 0 = 1 And 1 = 2;
- Select 'ok' From Dual Where 1 = 2 And 1 / 0 = 1;
證明了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;
- select * from temp where to_number(t2)>1 and t1='sz';
- select * from temp where t1='sz' and to_number(t2)>1;
在9i上執行, 第1條語句執行不會出錯,第2條語句會提示“無效的數字”
在10G上執行,兩條語句都不會出錯。
說明:9i上,Oracle SQL條件的執行確實是從右到左的,但是10G做了什麼調整呢?
實驗三:證明了在10g上SQL條件的執行是從右到左的
- Create Or Replace Function F1(v_In Varchar2) Return Varchar2 Is
- Begin
- Dbms_Output.Put_Line('exec F1');
- Return v_In;
- End F1;
- /
- Create Or Replace Function F2(v_In Varchar2) Return Varchar2 Is
- Begin
- Dbms_Output.Put_Line('exec F2');
- Return v_In;
- End F2;
- /
- SQL> set serverout on;
- SQL> select 1 from dual where f1('1')='1' and f2('1')='1';
- 1
- 1
- exec F2
- exec F1
- SQL> select 1 from dual where f2('1')='1' and f1('1')='1';
- 1
- 1
- exec F1
- exec F2
結果表明,Oracle SQL條件的執行順序是從右到左的。