您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關sql中in與exist效率是怎么樣的,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
一、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' 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不能完全互相替換,看具體的需求。如果選擇的列可以為空,則不能被替換。具體見:in/exists和notin/not exists語意探討
2、結論
not in 只有當子查詢中,select 關鍵字后的字段有not null約束或者有這種暗示時用notin,另外如果主查詢中表大,子查詢中的表小但是記錄多,則應當使用not in,并使用anti hashjoin.如果主查詢表中記錄少,子查詢表中記錄多,并有索引,可以使用not exists,另外not in最好也可以用或者外連接+isnull.一般情況下建議使用not exists
--比如:
SELECT
.. ....
FROM
ROLLUP
R
WHERE
NOT
EXISTS
(
SELECT
'Found'
FROMTITLE 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
ISNULL
;
--或者
SELECT
.... ..
FROM
ROLLUP
R
WHERE
OURCE_ID
NOT
IN
(
SELECT
OURCE_ID
FROM
TITLE T
WHERE
OURCE_ID
ISNOT
NULL
);
關于“sql中in與exist效率是怎么樣的”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。