2010-12-17 64 views
1

我有三個方法來構造我的查詢:什麼查詢將是最快的?

第一招:

select obj from table1 where condition1 and obj in (
select obj from table2 where condition2 and obj in (
select obj from table3 where condition3 and obj in (
... 
))) 

第二個:

select obj from table1 where condition1 
and obj in (select obj from table2 where condition2) 
and obj in (select obj from table3 where condition3) 
... 

第三個:

select table1.obj from table1 
inner join table2 on table2.obj = table1.obj and table2.condition='condition2' 
inner join table3 on table3.obj = table2.obj and table3.condition='condition3' 
... 
where table1.condition='condition1' 

我的問題如果這些查詢提供相同的結果並且這些查詢同樣優化。

我很確定,前兩個查詢產生相同的輸出,但第二個查詢更快。我不確定第三個查詢。

ADDED

還有另一種選擇:

select table1.obj from table1 
inner join table2 on table2.obj = table1.obj 
inner join table3 on table3.obj = table2.obj 
... 
where 
table1.condition='condition1' and 
table2.condition='condition2' and 
table3.condition='condition3' 
+0

你是否嘗試過所有3個基準測試? – scunliffe 2010-12-17 14:00:52

回答

1

雖然總是有例外,但選項3幾乎肯定是最好的/首選。根據您的索引和數據分佈,MySQL查詢執行計劃程序將處理從表中提取的順序。

在其他情況下,子查詢(選項1和2)針對執行外部查詢的每行 - 它們可能非常低效。因此,遵循前面的說法,嵌套子查詢(選項1)可能會比使用一階子查詢(選項2)或常規聯接(選項3)的指數級更差。

注意,對於INNER JOIN S,它不針對性能功能,如果額外的條件是在JOIN條款或條款WHERE重要。因此,您其他選項實際上等同於選項3

0

我會懷疑第三個查詢將是最快的。 SQL經過優化,可以使JOIN快速運行。

但是要知道您的數據的唯一方法是嘗試一下並查看。

1

Basicaly執行查詢的方法如下:從(得到整個數據)=> WHERE(應用約束)=> SELECT(顯示結果)

JOIN子句始終是連接數據的最佳選擇,因爲在WHERE子句中,只有與JOIN子句匹配的數據纔會被測試。

在獲取WHERE和SELECT的整個數據之前,在FROM中,只選擇ON子句中的字段並進行測試。

在您的兩個第一個示例中,對於每個SELECT,將爲WHERE子句的測試選擇表的全部內容。 加入WHERE子句幾乎是同樣的問題。

最後兩個例子似乎是一樣的。我更喜歡最後一個,因爲在第三個示例中使用ON子句對於RIGHT或LEFT JOIN是有用的,但在這種情況下,它只會在子句的使用中帶來混亂:FROM:獲取準確的資源,WHERE:應用約束。

這種解釋是非常簡略的,但我希望這是有道理的......

0

嗯,首先,這些查詢不一定返回相同的結果:

1. SELECT x FROM table1 WHERE x IN (SELECT x FROM table2 WHERE y = foo) 

2. SELECT x FROM table1 JOIN table 2 USING x WHERE table2.y = foo 

中()刪除重複。所以,如果table2包含滿足條件y = foo的x的50個值,則查詢2將返回比查詢1多50倍的行。這可能是您想要的或不是。如果x在兩個表中都是UNIQUE,那麼查詢會得到相同的結果。

子查詢(選項1和2)是用於與外部查詢

這當然是錯誤的的每行執行,因爲子查詢是不依賴子查詢。無論如何,它將執行一次子查詢,並對其進行散列或排序以消除重複項(按照IN()的要求),然後使用結果列表執行IN-join。 MySQL直到最近的版本確實爲每一行重新執行子查詢,這不再是這種情況。由於MySQL不會執行hash IN連接,它可能仍然比JOIN慢很多。

相關問題