SQL語(yǔ)句中not in 和not exist的區(qū)別
in 是把外表和內(nèi)表作hash 連接,而exists是對(duì)外表作loop循環(huán)乞而,每次loop循環(huán)再對(duì)內(nèi)表進(jìn)行查詢。
通常情況下認(rèn)為exist的效率比not in的效率高
not in 和not exists如果查詢語(yǔ)句使用了not in 那么內(nèi)外表都進(jìn)行全表掃描放祟,沒(méi)有用到索引;而not extsts 的子查詢依然能用到表上的索引跪妥。所以無(wú)論那個(gè)表大眉撵,用not exists都比not in要快落塑。
not in的使用方法
select name from student where name in ('zhang','wang','li','zhao');
等同于下面的用法:
select name from student where name='zhang' or name='li' or name='wang' or name='zhao'
exist的使用方法
select * from A where exists(
select c
from B
where c = A.c
)
盡量使用not exist ,避免使用not in
not in :會(huì)默認(rèn)調(diào)用子查詢
not exist :會(huì)調(diào)用關(guān)聯(lián)子查詢
1. 子查詢:
子查詢就是指的在一個(gè)完整的查詢語(yǔ)句之中污朽,嵌套若干個(gè)不同功能的小查詢龙考,從而一起完成復(fù)雜查詢的一種編寫(xiě)形式。子查詢根據(jù)子查詢對(duì)象的不同有多種分類炎功,但是不太重要。
- 單行單列:返回的是一個(gè)具體列的內(nèi)容蛇损,可以理解為一個(gè)單值數(shù)據(jù)坛怪;
- 單行多列:返回一行數(shù)據(jù)中多個(gè)列的內(nèi)容;
- 多行單列:返回多行記錄之中同一列的內(nèi)容更啄,相當(dāng)于給出了一個(gè)操作范圍沉帮;
- 多行多列:查詢返回的結(jié)果是一張臨時(shí)表;
下面的就是一種最簡(jiǎn)單的子查詢:
SELECT *
FROM emp e
WHERE e.sal=(
SELECT MIN(sal)
FROM emp)
2. 關(guān)聯(lián)子查詢
外部查詢的每一次結(jié)果待牵,都需要傳遞給子查詢,子查詢?nèi)缓蠓祷赜涗浿涤Ц茫獠坎樵兏鶕?jù)內(nèi)部查詢的結(jié)果做出一次查詢的結(jié)果川背。
例:檢索工資大于同職位的平均工資的員工信息蛤袒。
- 因此首先想到的思路是對(duì)職位分組妙真,這樣就能分別得到各個(gè)職位的平均工資
select job,avg(salary) from employee group by job;
select * from emp where sal >
( select avg(salary) from employee group by job);
上述代碼實(shí)際上是無(wú)法執(zhí)行的荚守,在進(jìn)行比較的時(shí)候也有較為明顯的錯(cuò)誤;
所謂的關(guān)聯(lián)子查詢如下:
select * from emp e where sal >
(select avg(sal) from emp where job = e.job);
容易看出外部 e 的對(duì)內(nèi)部子查詢的影響矗漾,如語(yǔ)句(where job = e.job)