【问题标题】:Adding a filter in WHERE versus FROM在 WHERE 与 FROM 中添加过滤器
【发布时间】:2013-05-15 14:10:19
【问题描述】:

所以我知道在查询的 WHERE 子句中添加过滤条件是一种很好的编程习惯,以便最大限度地减少连接中返回的行数,但是我们何时决定是否应该添加过滤器在 WHERE 而不是 FROM?例如:

SELECT a.ColA, a.ColB, a.ColC, b.ColD, b.ColE
FROM TblA a INNER JOIN TblB b
On a.ColA = b.ColD
AND a.ColA = 'X' 
AND a.ColB = 'Y'
WHERE b.ColD = 'ABC'

在这个查询中,如果我在 AND 子句中添加 b.ColD 而不是 WHERE 会怎样?这不会使查询更有效率吗?我知道有时两种方法的结果可能不同,但我不知道为什么?

谢谢。

【问题讨论】:

  • 从 tsql 标签判断,您使用的是 SQL Server。管理工作室能够显示查询的执行计划,因此您可以比较两个版本的差异。不过,我的猜测不会有太大区别。
  • 这不是重复的:OP 询问的是过滤器,而不是 JOIN
  • @gbn 我不确定 OP 的措辞(“过滤器”与“条件”等)是否如此重要,因为 OP 给出的示例与here 基本相同、hereherehere 等等。所有这些都有JOIN...ON,询问WHERE,并包含与您类似的答案。在我看来这个问题已经得到解答,还是我们也应该重新打开this question
  • @TimLehner:如果类似于提议的骗子的话。在这种情况下,我(和 dba.sw huys)将其读作“我应该在 JOIN 中过滤”而不是“我应该在 WHERE 中加入”。也许很微妙,但我是如何阅读这个问题的。 OP 还询问“在 JOIN 中过滤”是否更有效。他基本上是在询问单个查询中的谓词推送stackoverflow.com/a/6654525/27535
  • @gbn 除了第三个可能的例外,我的例子都是“我应该在 JOIN 中过滤”问题。无论如何,我想没有必要强调这一点。不过,您的回答非常好。

标签: sql sql-server performance tsql


【解决方案1】:

这很少对我的体验产生影响。可以,但不经常。 查询优化器可以解决这个问题,您无需再猜测。

不过,当使用 LEFT JOIN 时,它可能很重要,因为它会改变查询语义

一般情况下,I would separate JOIN and WHERE conditions for clarity and avoid ambiguities or partial/full cross joins。此答案仅供参考

注意:问题不是“JOIN in the WHERE difference”而是“WHERE in the JOIN difference”

我会这样做

SELECT
    a.ColA, a.ColB, a.ColC, b.ColD, b.ColE
FROM
    TblA a
    INNER JOIN
    TblB b On a.ColA = b.ColD
WHERE
     a.ColA = 'X' AND a.ColB = 'Y' AND b.ColD = 'ABC'

或者,如果更复杂并且我想让它更好读
如果优化器很愚蠢(很少见),这也会有所帮助:

SELECT
    a.ColA, a.ColB, a.ColC, b.ColD, b.ColE
FROM
    (SELECT ColA, ColB, ColC FROM TblA
     WHERE ColA = 'X' AND ColB = 'Y') a
    INNER JOIN
    (SELECT ColD, ColE FROM TblB WHERE ColD = 'ABC') b On a.ColA = b.ColD

在最后一种情况下,为了可读性

,也可以使用 CTE 来进一步分解它

【讨论】:

    【解决方案2】:

    在诸如 SQL 之类的声明性语言中,我发现尽可能具有声明性很有帮助,即将 JOIN 逻辑(“我想如何连接我的数据?”)与 WHERE 逻辑(“我该怎么办?想要过滤掉?”)。

    从技术上讲,它可能完全没有区别,但如果你强迫自己将两者分开,这是一个很好的理智检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-06
      • 2017-03-10
      • 2021-02-14
      • 2014-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多