【问题标题】:FIltering on the join?过滤加入?
【发布时间】:2011-06-23 21:05:30
【问题描述】:

与 WHERE 子句相反,是否有任何论点(性能方面)在连接中进行过滤?

例如,

SELECT blah FROM TableA a
INNER JOIN TableB b
ON b.id = a.id
AND b.deleted = 0
WHERE a.field = 5

相对

SELECT blah FROM TableA a
INNER JOIN TableB b
ON b.id = a.id
WHERE a.field = 5
  AND b.deleted = 0

我个人更喜欢后者,因为我觉得过滤应该在过滤部分(WHERE)进行,但是这两种方法有什么性能或其他原因吗?

【问题讨论】:

标签: sql-server inner-join


【解决方案1】:

如果查询优化器完成了它的工作,那么内连接的两种形式完全没有区别(除了其他形式的清晰度)。

也就是说,对于左连接,连接中的条件意味着在连接之前从第二个表中过滤掉行。 where 中的条件意味着在加入后从最终结果中过滤掉行。这些意味着非常不同的东西。

【讨论】:

  • 原始发布者使用的是内连接,而不是左连接。正如他所写,没有问题。
  • @Chogg 示例中使用内连接并不一定意味着问题仅与内连接有关。
【解决方案2】:

使用内部连接,您将获得相同的结果,并且可能具有相同的性能。但是,对于外连接,这两个查询将返回不同的结果,并且根本不等价,因为将条件放在 where 子句中本质上会将查询从左连接更改为内连接(除非您正在查找某些记录字段为空)。

【讨论】:

    【解决方案3】:

    这两者之间没有区别,因为在查询的逻辑处理中,WHERE 将始终紧跟在过滤子句(ON)之后,在您的示例中,您将拥有:

    1. 笛卡尔积(TableA 中的行数 x TableB 中的行数)
    2. 过滤器(开启)
    3. 在哪里。

    您的示例采用 ANSI SQL-92 标准,您也可以使用 ANSI SQL-89 标准编写查询,如下所示:

    SELECT blah FROM TableA a,TableB b
    WHERE b.id = a.id AND b.deleted = 0 AND a.field = 5
    

    这对于内部联接是正确的,外部联接是相似的,但不一样

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2021-11-07
      • 2020-03-09
      • 1970-01-01
      • 1970-01-01
      • 2017-08-13
      • 2018-10-05
      相关资源
      最近更新 更多