2013-10-25 75 views
1

你好:)我有一個關於MySQL查詢的問題。 哪個更快,爲什麼? 有什麼不同嗎?使用where語句而不是在SQL查詢中向join子句中添加條件會更好嗎?

select tab1.something, tab2.smthelse 
from tab1 inner join tab2 on tab1.pk=tab2.fk 
WHERE tab2.somevalue = 'value' 

或者這一個:

select tab1.something, tab2.smthelse 
from tab1 inner join tab2 on tab1.pk=tab2.fk 
AND tab2.somevalue = 'value' 
+0

對我來說似乎是一個不同的問題。原文是詢問哪個JOIN語法更好(ANSI vs theta)。這似乎是關於是否將JOIN子句或WHERE子句用於篩選條件。 –

+0

是的,我讀了很多關於類似問題的答案。儘管如此,我從來沒有找到一個,這正是我的答案 –

+0

這不是重複的! – Arth

回答

1

正如Simon指出的那樣,性能的差異應該可以忽略不計。主要擔心的是確保您的查詢正確表達您的意圖,並且(特別是)您會得到預期的結果。

只有在過濾器是連接條件時,才需要將過濾器添加到JOIN子句。在大多數情況下(不是全部),過濾器應該應用於WHERE子句,因爲它是整個查詢的過濾器,而不是連接本身。

AFAIK,這是真正影響查詢結果的唯一實例是使用OUTER JOIN時。

考慮以下查詢:

SELECT * 
FROM Customer c 
LEFT JOIN Orders o ON c.CustomerId = o.CustomerId 
WHERE o.OrderType = "InternetOrder" 

SELECT * 
FROM Customer c 
LEFT JOIN Orders o ON c.CustomerId = o.CustomerId AND o.OrderType = "InternetOrder" 

首先將返回一行有「網絡訂單」的訂單類型每個客戶訂單。實際上,由於應用於整個查詢的篩選器(即,沒有「InternetOrder」的客戶根本不會返回),所以您的左連接已成爲內連接。

第二個將返回每個客戶至少一行。如果客戶沒有訂單類型的「互聯網訂單」,它將爲所有訂單表字段返回空值。否則,它將針對每個類型爲「Internet訂單」的客戶訂單返回一行。

0

如果約束是基於關閉連接表(如你的是),那麼它是有道理的,當你加入到指定約束。

這樣,MySQL可以在連接時減少連接表中的行,否則它將需要能夠在應用WHERE邏輯之前選擇所有滿足基本連接條件的數據。

實際上,直到遇到更復雜的查詢或更大的數據集時,纔會發現性能差異不大,但是如果完成的更好,則限制每個JOIN中的數據會更有效,特別是如果連接表上有良好的索引。

相關問題