2013-03-18 98 views
27

我有兩個下面的例子。SQL JOIN在哪裏放置WHERE條件?

1例(WHERE)

SELECT 1 
    FROM table1 t1 
    JOIN table2 t2 ON t1.id = t2.id 
WHERE t2.field = true 

2例(加入和)

SELECT 1 
    FROM table1 t1 
    JOIN table2 t2 ON t1.id = t2.id AND t2.field = true 

什麼是性能方面的更快的方法?你喜歡哪個?

回答

16

如果過濾器在功能上以JOIN條件進入(即,它是實際的連接條件,而不僅僅是過濾器),則它必須出現在該連接的ON子句中。

值得注意:

  • 如果你把它放在WHERE從句中代替,性能是相同的,如果連接是INNER,否則不同。正如在評論中提到的那樣,這無關緊要,因爲無論如何,結果是不同的。

  • 放置過濾器的WHERE子句中時,它確實是一個OUTER JOIN條件隱含取消OUTER性質的條件(「時,有沒有記錄加入連」),因爲這些過濾器意味着在第一必須有現有記錄地點。例如:

... table1 t LEFT JOIN table2 u ON ... AND t2.column = 5是正確的

... table1 t LEFT JOIN table2 u ON ... 
WHERE t2.column = 5 

是不正確,因爲t2.column = 5告訴從T2記錄發動機預計,這違背了外部聯接。例外,這將是一個IS NULL過濾器,例如WHERE t2.column IS (NOT) NULL(這實際上是建立條件外一種方便的方式連接)

  • LEFTRIGHT連接是隱含OUTER聯接。

希望它有幫助。

+2

此答案包含一些錯誤和混亂的文字。 1.對於INNER JOIN,只要沒有插入的OUTER JOIN,任何條件都可以在WHERE而不是ON。 2.當將LEFT JOIN條件從ON移動到WHERE時,由於(如您所說)一般情況下結果不同,所以性能無關。 3.這種差異通常不會將「外部連接轉換爲內部連接」。 – philipxy 2016-06-27 12:16:01

+0

@philipxy你是對的,我試圖清理一下 – Sebas 2017-05-01 10:44:37

+0

「過濾器在JOIN條件下功能上進入」還是「[過濾器]是實際連接條件,而不僅僅是過濾器」是什麼意思?無論如何,「只是一個過濾器」的概念是沒有用的,因爲'JOIN ON c AND d'與'JOIN ON c WHERE d'相同。 (實際上,SQL標準*根據JOIN WHERE定義* JOIN ON。)類似地,「隱式地取消條件的OUTER特性」*僅僅不傳遞任何東西*。你似乎同意你的看法,因爲你用恐嚇引語(因此本身不清楚)對它進行註釋「(」即使沒有記錄也加入)「。你沒有解釋。 – philipxy 2017-05-01 11:01:35

5

JOIN條件通常應與過濾條件無關。您可以用ON定義您的加入規則(如何)。你過濾什麼你想WHERE。性能方面,所有發動機和設計都沒有一般規則,所以你的里程會有很大差異。

0

我認爲更快的方法是將過濾器放在where子句中,因爲它會先在where,然後是join子句中進行過濾,所以不需要過濾器的置換。

+0

DBMS與任何優化都沒有區別。例如,請參閱SELECT/JOIN優化中的MySQL文檔:將INNER JOIN的ON視爲應用於該JOIN的WHERE。 – philipxy 2016-06-27 12:20:54