天天看點

查詢在一張表不在另外一張表的記錄

<a href="http://hi.baidu.com/zdfgng/blog/item/dd5f88359a1cd0260b55a9ce.html">http://hi.baidu.com/zdfgng/blog/item/dd5f88359a1cd0260b55a9ce.html</a>

假如要查詢在a表中存在,但是在b表中不存在的記錄,應該如何查詢。為了便于說明,我們假設a表和b表都隻有一個字段id,a表中的記錄為{1,2,3,4,5},b表中的記錄為{2,4},那麼我們需要通過一個sql查詢得到{1,3,5}這樣的結果集。

看到這個題目,我們首先想到的可能就是not in這樣的關鍵字,具體的查詢語句如下:

上述查詢語句的查詢結果集确實是{1,3,5},用navicat執行上述語句,得到如下圖所示結果:

查詢在一張表不在另外一張表的記錄

但是仔細分析我們可以發現,如果b表很長,那麼執行上述的查詢語句,需要用a表中的字段去比對b表中的每一個字段,相當于是a表的每一個字段都要周遊一次b表,效率非常低下。(隻要a中的字段不在b表中那麼肯定要周遊完b表,如果a表中的字段在b表中,那麼隻要周遊到就退出,進行a表中下一個字段的比對)

連接配接查詢使我們平時進行sql查詢用到最多的操作之一了,相對于上述not in關鍵字,我們使用連接配接查詢的效率更高。因為我們需要搜尋的是a表中的内容,是以使用a表左連接配接b表,這樣b表中會補null,查詢語句如下:

上述查詢語句的查詢結果如下:

查詢在一張表不在另外一張表的記錄

因為a、b兩表中字段id相同,是以上述b表中的id字段變成了id1。仔細觀察由可以發現,我們需要的結果集{1,3,5}所對應的id1字段都是null。這樣我們在上述的查詢語句中加入條件即可完成對隻在a表中,但不在b表中的結果集的插叙,查詢語句如下:

查詢結果如下圖所示:

查詢在一張表不在另外一張表的記錄

但是我們又發現上述查詢結果有2列,也就是a表和b表的連接配接查詢結果,但是我們隻需要a表中的内容,是以對上述查詢稍作修改:

查詢在一張表不在另外一張表的記錄

以上就是我們所要求的查詢結果。

查詢在一張表不在另外一張表的記錄

View Code

我們能夠寫出來的最直覺的TSQL語句應該是:

然後我們看看這個語句的查詢計劃:

查詢在一張表不在另外一張表的記錄
查詢在一張表不在另外一張表的記錄

從上圖我們可以發現使用了Nested Loops的聯接方式,但是我們知道nested loop聯接方式的使用場景是:比較适合于兩個比較小的結果集做聯接,或者至少是Outer table的結果集比較小。而上面的outer table是ta,它是大表,是以可以發現nested loop不适合。注意:雖然上面的查詢語句中沒有join字段,但是還是使用了join。

假如我們使用left join 來寫查詢語句的話,sql server會幫我們選擇何種聯接方式呢?測試如下:

上述查詢的執行執行計劃如下圖所示:

查詢在一張表不在另外一張表的記錄
查詢在一張表不在另外一張表的記錄

從上圖我們可以發現sql server幫我們選擇了使用Hash Match。這是因為在上述聯接中,ta是大表,ta和tb兩表之間資料量差距很大,還有ta和tb都沒有索引。從執行計劃的TotalSubtreeCost中也可以看出來,使用Hash Match的TotalSubtreeCost=0.12,而是用Nested Loop的TotalSubtreeCost=1.03。可以發現Hash Match性能比Nest Loop好很多。

那麼使用Merge Join能,起性能如何?我們可以通過使用sql hint來建議sql server使用特定的聯接方式,執行如下TSQL語句:

其執行計劃如下圖所示:

查詢在一張表不在另外一張表的記錄
查詢在一張表不在另外一張表的記錄

從上圖可以看出:

因為查詢列上都沒有索引,是以查詢出來的結果不一定是排序的,這樣sql server幫我們做了排序操作。

在做完排序操作以後進行的是Merge Join操作,整個查詢所使用的TotalSubtreeCost=0.69,好于Nested Loop,比Hash Match性能差。

是以我們在回答上面題目的時候,必須說明使用Hash Match,而不隻是給出left join的答案,之是以查詢結果最有是因為sql server幫我們分析了使用Hash Match性能最優。

所有查詢方式:

查詢在一張表不在另外一張表的記錄

 本文轉自xwdreamer部落格園部落格,原文連結:http://www.cnblogs.com/xwdreamer/archive/2012/06/01/2530597.html,如需轉載請自行聯系原作者