注意Left Join時過濾條件擺放的位置,不同的位置可是會有不同的結果歐

今天同仁問我一個TSQL問題,語法如下

Select * From Tb1 a
Left Join Tb2 b On a.id=b.id
Where b.name='Rock'

 

同仁執行上述語法後發現Select出來的結果跟他想的不一樣,他發現Select出來的結果居然跟Inner Join一樣,而非他想要的Left Join結果。

我第一時間也覺得怎會這樣呢?因此手寫了一個簡單的測試,測試語法如下圖如上圖所示,我們在Inner Join時對於過濾條件的擺放位置通常不是擺在Join當下就是擺在最後用Where來過濾資料。由上圖可以知道不管放哪一個位置,我們皆可得到同樣的結果。

 

然而今日同事就被這既定印象給誤導了,他在Left Join時也認為兩個擺放位置都會得到相同結果。是這樣嗎? 我們測試一下,測試語法如下圖。透過上圖實驗,我們可以看見Left Join對於過濾條件擺放的位置不同給予了不同的結果 ( 跟Inner Join不一樣 )。

第一種寫法法是先過濾再Join,而第二種就是先Join出結果然後再過濾出資料。只是以往用在Inner Join會是一樣的結果,然後就被誤導成只要是Join兩種做法得到的結果都是一樣。所以日後在Left Join時請大家要注意這一點歐。

 

在找尋問題時,我想到一個問題如果先Join再過濾資料,萬一兩張資料量非常巨大的資料表做Join,那不是會造成非常大的Loading嗎 ? 因此我有看了一下執行計畫,執行計畫如下圖所示。我們可以從上圖看見SQL將Join由Left Join改為Inner Join。這是為何呢 ? 其實仔細想一下,先Join再過濾其實跟Inner Join是一樣的,因此SQL用這種方式來避掉兩張資料量非常巨大的資料表做Left Join。

 

 

我是ROCK

rockchang@mails.fju.edu.tw