㈠ 在sql語句中,in和exist的區別是什麼
in是把外表和內表作hash連接,而exists是對外表作loop循環。
㈡ SQL語句中「in」和「exist」有什麼區別
本文主要分析了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 次
㈢ 關於查詢語句中的in和exists的區別
1、適用表的類型不同。
in是子查詢為驅動表,外面的表為被驅動表,故適用於子查詢結果集小而外面的表結果集大的情況。
exists是外面的表位驅動表,子查詢裡面的表為被驅動表,故適用於外面的表結果集小而子查詢結果集大的情況。
2、子查詢關聯不同。
exists一般都是關聯子查詢。對於關聯子查詢,必須先執行外層查詢,接著對所有通過過濾條件的記錄,執行內層查詢。外層查詢和內層查詢相互依賴,因為外層查詢會把數據傳遞給內層查詢。
in則一般都是非關聯子查詢,非關聯子查詢則必須先完成內層查詢之後,外層查詢才能介入。
3、執行次數不同。
IN 語句:只執行一次,確定給定的值是否與子查詢或列表中的值相匹配。in在查詢的時候,首先查詢子查詢的表,然後將內表和外表做一個笛卡爾積,然後按照條件進行篩選。所以相對內表比較小的時候,in的速度較快。
EXISTS語句:執行次數根據表的長度而定。指定一個子查詢,檢測行的存在。遍歷循環外表,然後看外表中的記錄有沒有和內表的數據一樣的。匹配上就將結果放入結果集中。
SQL語句語言特點:
1、SQL風格統一
SQL可以獨立完成資料庫生命周期中的全部活動,包括定義關系模式、錄人數據、建立資料庫、査詢、更新、維護、資料庫重構、資料庫安全性控制等一系列操作,這就為資料庫應用系統開發提供了良好的環境,在資料庫投入運行後,還可根據需要隨時逐步修改模式,且不影響資料庫的運行,從而使系統具有良好的可擴充性。
2、高度非過程化
非關系數據模型的數據操縱語言是面向過程的語言,用其完成用戶請求時,必須指定存取路徑。而用SQL進行數據操作,用戶只需提出「做什麼」,而不必指明「怎麼做」,因此用戶無須了解存取路徑,存取路徑的選擇以及SQL語句的操作過程由系統自動完成。這不但大大減輕了用戶負擔,而且有利於提高數據獨立性。
㈣ sql 中的in 和exists區別
in和exists在功能上本質沒有區別,唯一的區別就在於性能。也就是說同樣的sql你用那個執行效率高的問題。
其實說簡單點就是exists用到了關聯,而in是在一個大的數據及合理篩選,這么說性能的優劣你就很明白了吧。關聯的速度是要大於篩選的,所以你只要能用exists就別用in,這是寫出好的sql語句的基本規則。
exists是查詢是否存在,它後邊跟的語句是查詢*還是直接寫個1,效果都一樣,比如你看到的sql的例子,我把*改成1,結果都一樣的。
select sno,sname,sdept
from student s1
where exists
(select 1 --*
from student s2
where s2.dept=s1.depe
and s2.name='小劉');
比如說這個例子學生表被賦予了兩個別名s1和s2
語句中要求dept和depe相等,我把上邊的語句改一下你可能就明白他的意思了:
select sno,sname,sdept
from student s1 ,student s2
where s1.dept =s2.depe
and s1.name = '小劉';
語句就是為了要看出student表中某兩行或者多行之間的關系,所以要對自己關聯,你仔細看一下你所面對的student表的每一列,就可能看明白了。
記住sql不要從技術上去理解,你就直接把它的功能用漢字表達出來,然後去理解就行了,跟我們說話時一個樣的:
從表student中找到dept和(student表中)depe相同的名字叫小劉的學生
㈤ SQL中 exists和in的區別是什麼啊
11. 用EXISTS替代IN、用NOT EXISTS替代NOT IN
在許多基於基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率. 在子查詢中,NOT IN子句將執行一個內部的排序和合並. 無論在哪種情況下,NOT IN都是最低效的 (因為它對子查詢中的表執行了一個全表遍歷). 為了避免使用NOT IN ,我們可以把它改寫成外連接(OUTER JOINS)或NOT EXISTS.
例子:(高效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND EXISTS (SELECT 『X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 『MELB』)
(低效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = 『MELB』)
12. 用EXISTS替換DISTINCT
當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT. 一般可以考慮用EXIST替換, EXISTS 使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足後,立刻返回結果。
例:(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO
(高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT 『X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
㈥ SQL關於IN和EXISTS的區別
IN
確定給定的值是否與子查詢或列表中的值相匹配。
EXISTS
指定一個子查詢,檢測行的存在。
比較使用 EXISTS 和 IN 的查詢
exists()後面的子查詢被稱做相關子查詢 他是不返回列表的值的.只是返回一個ture或false的結果,其運行方式是先運行主查詢一次 再去子查詢里查詢與其對應的結果 如果是ture則輸出,反之則不輸出.再根據主查詢中的每一行去子查詢里去查詢.
in()後面的子查詢 是返回結果集的,換句話說執行次序和exists()不一樣.子查詢先產生結果集,然後主查詢再去結果集里去找符合要求的欄位列表去.符合要求的輸出,反之則不輸出.