2013-03-18 70 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