in和exists的SQL執行效率分析
A,B兩個表,
(1)當只顯示一個表的數據如A,關係條件只一個如ID時,使用IN更快:
select * from A where id in (select id from B) select * from A
(2)當只顯示一個表的數據如A,關係條件不只一個如ID,col1時,使用IN就不方便了,可以使用EXISTS
where 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
所以使用何種方式,要根據要求來定。
SQL中in可以分爲三類:
1、形如select * from t1 where f1 in ('a','b'),應該和以下兩種比較效率
2、形如select * from t1 where f1 in (select f1 from t2 where t2.fx='x'),
select * from t1 where f1='a' or f1='b'或者 select * from t1 where f1 ='a' union all select * from t1 f1='b'
其中子查詢的where裏的條件不受外層查詢的影響,這類查詢一般情況下,自動優化會轉成exist語句,也就是效率和exist一樣。
3、形如select * from t1 where f1 in (select f1 from t2 where t2.fx=t1.fx),
其中子查詢的where裏的條件受外層查詢的影響,這類查詢的效率要看相關條件涉及的字段的索引情況和數據量多少,一般認爲效率不如exists。除了第一類in語句都是可以轉化成exists 語句的SQL,一般編程習慣應該是用exists而不用in,而很少去考慮in和exists的執行效率.
in和exists
in 是把外表和內表作hash 連接,而exists是對外表作loop循環,每次loop循環再對內表進行查詢。一直以來認爲exists比in效率高的說法是不準確的。
如果查詢的兩個表大小相當,那麼用in和exists差別不大。
如果兩個表中一個較小,一個是大表,則子查詢表大的用exists,子查詢表小的用in:
例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;而not extsts 的子查詢依然能用到表上的索引。所以無論那個表大,用not exists都比not in要快。
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'
的結果是相同的。
//-----------------------------------------------------
1.All:對所有數據都滿足條件,整個條件才成立,例如:5大於所有返回的id
select *
from A
where 5>All(select id from A)
go
2.Any:只要有一條數據滿足條件,整個條件成立,例如:3大於1,2
select *
from A
where 3>any(select id from A)
go
3.Some和Any一樣
--end