SQL where條件順序對效能無影響

2021-08-27 15:02:24 字數 3305 閱讀 6789

**:無盡空虛

經常有人問到oracle中的where子句的條件書寫順序是否對sql效能有影響,我的直覺是沒有影響,因為如果這個順序有影響,oracle應該早就能夠做到自動優化,但一直沒有關於這方面的確鑿證據。在網上查到的文章,一般認為在rbo優化器模式下無影響(10g開始,預設為rbo優化器模式),而在cbo優化器模式下有影響,主要有兩種觀點:

a.能使結果最少的條件放在最右邊,sql執行是按從右到左進行結果集的篩選的

b.有人試驗表明,能使結果最少的條件放在最左邊,sql效能更高。

實驗一:證明了sql的語法分析是從右到左的

下面的試驗在9i和10g都可以得到相同的結果: 第1條語句執行不會出錯,第2條語句會提示除數不能為零。

1.select 'ok' from dual where 1 / 0 = 1 and 1 = 2;

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;

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上執行, 第1條語句執行不會出錯,第2條語句會提示「無效的數字」

在10g上執行,兩條語句都不會出錯。

說明9i上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----------

1exec f2

exec f1

sql> select 1 from dual where f2('1')='1' and f1('1')='1';

1----------

1exec f1

exec f2

結果表明,sql條件的執行順序是從右到左的。

實驗四:證明了條件的順序對效能沒有影響

根據這個結果來分析,把能使結果最少的條件放在最右邊,是否會減少其它條件執行時所用的記錄數量,從而提高效能呢?例如下面的sql條件,是否應該調整sql條件的順序呢?

where a.結帳id is not null

and a.記錄狀態<>0

and a.記帳費用=1

and (nvl(a.實收金額, 0)<>nvl(a.結帳金額, 0) or nvl(a.結帳金額, 0)=0)

and a.病人id=[1] and instr([2],','||nvl(a.主頁id,0)||',')>0

and a.登記時間between [3] and [4]

and a.門診標誌<>1

實際上從這條sql語句的執行計畫來分析,oracle首先會找出條件中使用索引或表間連線的條件,以此來過濾資料集,然後對這些結果資料塊所涉及的記錄逐一檢查是否符合所有條件,所以條件順序對效能幾乎沒有影響。如果沒有索引和表間連線的情況,條件的順序是否對效能有影響呢?再來看乙個實驗。

sql> select count(*) from診療專案目錄where操作型別='1';

count(*)

----------

3251

sql> select count(*) from診療專案目錄where類別='z';

count(*)

----------

170sql> select count(*) from診療專案目錄where類別='z' and操作型別='1';

count(*)

----------

1declare

v1 varchar2(20);

begin

for i in 1 .. 1000 loop

--select名稱into v1 from診療專案目錄where類別= 'z' and操作型別= '1';

select名稱into v1 from診療專案目錄where操作型別='1' and類別='z';

end loop;

end;

/上面的sql按兩種方式分別執行了1000次查詢,結果如下:

操作型別='1'在最右 | 類別='z'在最右

0.093 | 1.014

1.06 | 0.999

0.998 | 1.014

按理說,從右到左的順序執行,「類別='z'」在最右邊時,先過濾得到170條記錄,再從中找符合「操作型別 = '1'」的,比較而言,「操作型別 = '1'」在最右邊時,先過濾得到3251條記錄,再從中找符合「類='z'」,效率應該要低些,而實際結果卻是兩者所共的時間差不多。

其實,從oracle的資料訪問原理來分析,兩種順序的寫法,執行計畫都是一樣的,都是全表掃瞄,都要依次訪問該錶的所有資料塊,對每乙個資料塊中的行,逐一檢查是否同時符合兩個條件。所以就不存在先過濾出多少條資料的問題。

綜上所述,where子句中條件的順序對效能沒有影響(不管是cbo還是rbo優化器模式),注意,額外說一下,這裡只是說條件的順序,不包含表的順序。在rbo優化器模式下,表應按結果記錄數從大到小的順序從左到右來排列,因為表間連線時,最右邊的表會被放到巢狀迴圈的最外層。最外層的迴圈次數越少,效率越高。

SQL where 條件順序對效能的影響有哪些

從oracle的資料訪問原理來分析,兩種順序的寫法,執行計畫都是一樣的,都是全表掃瞄,都要依次訪問該錶的所有資料塊,對每乙個資料塊中的行,逐一檢查是否同時符合兩個條件。所以,就不存在先過濾出多少條資料的問題。綜上所述,where子句中條件的順序對效能沒有影響 不管是cbo還是rbo優化器模式 注意,...

SQL where條件的優化

原則,多數資料庫都是從 左到右的順序處理條件,把能過濾更多資料的條件放在前面,過濾少的條件放後面 sql1 select from employee where salary 1000 條件1,過濾的資料較少 and dept id 01 條件2,過濾的資料比條件1多 上面的sql就不符合我們的原則...

SQL條件的順序對資料庫效能的影響

經常有人問到oracle中的where子句的條件書寫順序是否對sql效能有影響,我的直覺是沒有影響,因為如果這個順序有影響,oracle應該早就能夠做到自動優化,但一直沒有關於這方面的確鑿證據。在網上查到的文章,一般認為在rbo優化器模式下無影響 10g開始,預設為rbo優化器模式 而在cbo優化器...