in/exists和not in/not exists執行效率
http://blog.csdn.net/maoweiting19910402/article/details/8363979
一、IN 與EXISTS
1、理解
IN的執行流程
SELECT * FROM T1 WHERE X IN (SELECT Y FROM T2)
事實上可以理解為:
SELECT * FROM T1, (SELECT DISTINCT Y FROM T2) T2 WHERE T1.X = T2.Y
從這裡可以看出,IN需要先處理T2表,然後再和T1進行關聯
EXISTS的執行流程
SELECT * FROM T1 WHERE EXISTS (SELECT NULL FROM T2 WHERE Y = X) --可以理解為: for x in ( select * from t1 ) LOOP if ( exists ( select null from t2 where y = x.x )THEN OUTPUT THE RECORD end if end loop |
從這裡看出,EXISXTS會先查詢T1表,然後再LOOP處理T2表
2、結論
對於in 和 exists的區別: 如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in, 反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。其實我們區分in和exists主要是造成了驅動順序的改變(這是效能變化的關鍵),如果是exists,那麼以外層表為驅動表,先被訪問,如果是IN,那麼先執行子查詢,所以我們會以驅動表的快速返回為目標,那麼就會考慮到索 引及結果集的關係了。
綜合以上對IN/EXISTS的討論,我們可以得出一個基本通用的結論:IN適合於外表大而內表小的情況;EXISTS適合於外表小而內表大的情況。
二、NOT IN 與NOT EXISTS
1、理解
NOT IN的執行流程
SELECT * FROM T1 WHERE X NOT IN (SELECT Y FROM T2)
事實上可以理解為:
SELECT * FROM T1, (SELECT DISTINCT Y FROM T2) T2 WHERE T1.X != T2.Y
NOT EXISTS的執行流程
SELECT .. .. . FROM ROLLUP R WHERE NOT EXISTS (SELECT 'Found' FROM TITLE T WHERE R.SOURCE_ID = T.TITLE_ID); --可以理解為: for x in ( select * from rollup ) loop if ( not exists ( that query ) ) then OUTPUT end if; end; |
注意:NOT EXISTS 與 NOT IN 不能完全互相替換,看具體的需求。如果選擇的列可以為空,則不能被替換。具體見:
2、結論
not in 只有當子查詢中,select 關鍵字後的欄位有not null約束或者有這種暗示時用not in,另外如果主查詢中表大,子查詢中的表小但是記錄多,則應當使用not in,並使用anti hash join.如果主查詢表中記錄少,子查詢表中記錄多,並有索引,可以使用not exists,另外not in最好也可以用/*+ HASH_AJ */或者外連線+is null.一般情況下建議使用not exists
--比如: SELECT .. .. .. FROM ROLLUP R WHERE NOT EXISTS (SELECT 'Found' FROM TITLE T WHERE R.SOURCE_ID = T.TITLE_ID); --改成 SELECT .. .. .. FROM TITLE T, ROLLUP R WHERE R.SOURCE_ID = T.TITLE_ID(+) AND T.TITLE_ID IS NULL; --或者 SELECT /*+ HASH_AJ */ .. .. .. FROM ROLLUP R WHERE OURCE_ID NOT IN (SELECT OURCE_ID FROM TITLE T WHERE OURCE_ID IS NOT NULL); |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14710393/viewspace-757972/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MYSQL 中 exists 語句執行效率變低MySql
- [Oracle] exists 和 not existsOracle
- 淺談Oracle中exists與in的執行效率問題Oracle
- MySQL exists 優化 in 效率MySql優化
- oracle中關於in和exists,not in 和 not existsOracle
- NOT IN、JOIN、IS NULL、NOT EXISTS效率對比Null
- exists和not exists及in和not in的用法與區別
- oracle中的exists和not exists和in用法詳解Oracle
- oracle中的exists 和not exists 用法詳解Oracle
- SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差別SQL
- EXISTS、IN、NOT EXISTS、NOT IN用法區別
- In和exists使用及效能分析(二):exists的使用
- In和exists使用及效能分析(三):in和exists的效能分析
- in 和 exists區別
- Oralce 使用SQL中的exists 和not exists 用法詳解SQL
- 對IN & EXISTS NOT IN & NOT EXISTS的優化優化
- EXISTS、IN、NOT EXISTS、NOT IN的區別(ZT)
- sql:delete if exists還是drop if exists?SQLdelete
- exists和連線方式
- in,exists和not exists ,not in與null的一些關係記載Null
- 【SQL】existsSQL
- mysql 關於exists 和in分析MySql
- [Oracle] minus 和 not exists比較Oracle
- Exists和IN的原理解析
- ORACLE 中IN和EXISTS比較Oracle
- 透過sql trace比較常規 not in 、minus、not exists效率SQL
- 通過sql trace比較常規 not in 、minus、not exists效率SQL
- 理解exists count
- oracle exists and not existOracle
- oracle中in和exists的區別Oracle
- (轉)ORACLE 中IN和EXISTS比較Oracle
- MySQL之in與existsMySql
- oracle 用EXISTS替代INOracle
- SQL語句中exists和in的區別SQL
- (轉)ORACLE 中IN和EXISTS的區別Oracle
- in和exists的一些區別
- SQL中IN和EXISTS用法的區別SQL
- Oracle中exists和in的效能差異Oracle