SQL語句中in和exist有什麼區別

2021-05-23 18:36:56 字數 2628 閱讀 6216

1樓:手機使用者

本文主要分析了in和exists的區別與執行效率的問題:

in可以分為三類:

1、形如select * from t1 where f1 in ( 'a ', 'b '),應該和以下兩種比較效率。

select * from t1 where f1= 'a ' or f1= 'b '

或者 select * from t1 where f1 = 'a ' union all select * from t1 f1= 'b '

你可能指的不是這一類,這裡不做討論。

2、形如

select * from t1 where f1 in (select f1 from t2 where t2.fx= 'x '),

其中子查詢的where裡的條件不受外層查詢的影響,這類查詢一般情況下,自動優化會轉成exist語句,也就是效率和exist一樣。

3、形如

select * from t1 where f1 in (select f1 from t2 where t2.fx=t1.fx),

其中子查詢的where裡的條件受外層查詢的影響,這類查詢的效率要看相關條件涉及的欄位的索引情況和資料量多少,一般認為效率不如exists。

除了第一類in語句都是可以轉化成exists 語句的,一般程式設計習慣應該是用exists而不用in.

a,b兩個表,

(1)當只顯示一個表的資料如a,關係條件只一個如id時,使用in更快:

select * from a where id in (select id from b)

(2)當只顯示一個表的資料如a,關係條件不只一個如id,col1時,使用in就不方便了,可以使用exists:

select * from awhere exists (select 1 from b where id = a.id and col1 = a.col1)

(3)當只顯示兩個表的資料時,使用in,exists都不合適,要使用連線:

select * from a left join b on id = a.id

所以使用何種方式,要根據要求來定。

這是一般情況下做的測試:

測試結果:

set statistics io on select * from sysobjects where exists (select 1 from syscolumns where id=syscolumns.id) select * from sysobjects where id in (select id from syscolumns ) set statistics io off (47 行受影響)

表 'syscolpars '。掃描計數 1,邏輯讀取 3 次,物理讀取 0 次,預讀 2 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

表 'sysschobjs '。掃描計數 1,邏輯讀取 3 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

(1 行受影響)

(44 行受影響)

表 'syscolpars '。掃描計數 47,邏輯讀取 97 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

表 'sysschobjs '。掃描計數 1,邏輯讀取 3 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

(1 行受影響)

set statistics io on select * from syscolumns where exists (select 1 from sysobjects where id=syscolumns.id) select * from syscolumns where id in (select id from sysobjects ) set statistics io off

(419 行受影響)

表 'syscolpars '。掃描計數 1,邏輯讀取 10 次,物理讀取 0 次,預讀 15 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

表 'sysschobjs '。掃描計數 1,邏輯讀取 3 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

(1 行受影響)

(419 行受影響)

表 'syscolpars '。掃描計數 1,邏輯讀取 10 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

表 'sysschobjs '。掃描計數 1,邏輯讀取 3 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

(1 行受影響)

測試結果(總體來講exists比in的效率高):

效率:條件因素的索引是非常關鍵的

把syscolumns 作為條件:syscolumns 資料大於sysobjects

用in掃描計數 47,邏輯讀取 97 次,

用exists

掃描計數 1,邏輯讀取 3 次

把sysobjects作為條件:sysobjects的資料少於syscolumns

exists比in多預讀 15 次

兩條sql語句union排序,SQL語句中UNION排序問題

order by 放裡面 select starttime,endtime from select from table order by starttime asc where endtime getdate union select starttime,endtime from select f...

oracle的sql的select語句中有limit嗎

limit是mysql裡的,select from a order by b limit 6,1,取得按b排序的第6行a的值 而在oracle中想要實現是通過rownum select from a where rownum 6 order by b rownum是一個序列,是oracle資料庫從資...

sql連線查詢語句中from子句中表的順序有什麼要求

嚴格上來說是沒有要求的,他們有兩種寫法,一種是ansi sql,一種是trans sql.ansi sql select from table1,table2,table3 where table1.id table2.id and table3.id table2.pid trans sql se...