sql in與exists相關效能問題總結
in 和 exists的是dba或開發人員日常工作學習中常用的基本運算子,今天我就這兩個所帶來的效能問題進行分析總結,方便自己與他人的後續學習與工作。
先來了解in 和 exists的效能區別: 如果主查詢中的表較大且又有索引,子查詢得出的結果集記錄較少時,應該用in;反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。
舉例說明: select * from a where a.id in(select b.id from b )
select * from a where exists(select 1 from b where a.id=b.id)
其中,第一句in字句使用的是外層a表的索引,括號中的b全表掃瞄,所以,當a表巨大而b表很小的時候,此時效能較高,反之效能很差;
第二句exists字句中使用的是內層b表的索引,外面a全表掃瞄,所以,當b表巨大而a表很小的時候,此時效能較高,反之效能很差。
區分in和exists主要是造成了驅動順序的改變(這是效能變化的關鍵),如果是exists,那麼以外層表為驅動表,先被訪問,如果是in,那麼先執行子查詢,再以in為驅動表,去查詢外層表中符合要求的記錄,所以我們會以驅動表的快速返回為目標,那麼就會考慮到索引及結果集的關係了。
a) in的執行順序:
1.首先執行一次子查詢,子查詢先產生結果集;
2. 然後主查詢再去結果集裡去找符合要求的字段列表去.符合要求的輸出,反之則不輸出。
b) exists的執行順序:
1.首先執行一次外部查詢;
2.對於外部查詢中的每一行分別執行一次子查詢,而且每次執行子查詢時都會引用外部查詢中當前行的值;
3.使用子查詢的結果true或false來確定外部查詢的結果集。
例如:表a(小表),表b(大表)
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列的索引。
相反的:
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列的索引。
exists適合外表結果集很小的情況;in適合外表結果集很大,而內錶結果集較小的情況。
這裡首先要說,not in 邏輯上不完全等同於not exists,當子查詢中返回的任意一條記錄含有空值,則not in查詢將不返回任何記錄;當子查詢欄位有非空限制,這時可以使用not in。
1、對於not exists查詢,內錶存在空值對查詢結果沒有影響;對於not in查詢,內錶存在空值將導致最終的查詢結果為空。
2、對於not exists查詢,外表存在空值,存在空值的那條記錄最終會輸出;對於not in查詢,外表存在空值,存在空值的那條記錄最終將被過濾,其他資料不受影響。
3、解釋為什麼not in語句比not exists語句效率差這麼多(not in 不走索引):
not exists語句很顯然就是乙個簡單的兩表關聯,內錶與外表中存在空值本身就不參與關聯;
not exists的執行順序是:在表中查詢,是根據索引查詢的,如果存在就返回true,如果不存在就返回false,不會每條記錄都去查詢。
not in的執行順序是:是在表中一條記錄一條記錄的查詢(查詢每條記錄)符合要求的就返回結果集,不符合的就繼續查詢下一條記錄,直到把表中的記錄查詢完。也就是說為了證明找不到,所以只能查詢全部記錄才能證明,並沒有用到索
引。
統計 相關性與自相關性
相關係數度量指的是兩個不同事件彼此之間的相互影響程度 而自相關係數度量的是同一事件在兩個不同時期之間的相關程度,形象的講就是度量自己過去的行為對自己現在的影響。自相關,也稱 序列相關。是乙個訊號於其自身在不同時間點的互相關。非正式地來說,它就是兩次觀察之間的相似度對它們之間的時間差的函式。它是找出重...
spearman相關性分析 相關性分析
r語言常用函式 cor 預設結果為矩陣 cor mydat,use method use 缺失值的處理,method 處理方法 cor x,y 可以計算非方形矩陣,x y分別為2個矩陣,相同的行數 cor.test x,y,alternative method x y為檢驗相關性的變數 librar...
SQL in與exists查詢的區別
先來簡單看看兩個查詢 in 等價於 1 select sno from student where s in 男 先執行in中的查詢 2 select sno,cno,grade from sc where sc.sno student.sno 以上in 中的查詢只執行一次,它查詢出student中...