在WHERE和FROM中添加过滤器

时间:2013-05-15 14:10:19

标签: sql sql-server performance tsql

所以我知道在查询的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子句而不是WHERE中添加b.ColD怎么办?这会不会使查询更有效率?我知道两种方法的结果有时会有所不同,但我不知道为什么?

感谢。

2 个答案:

答案 0 :(得分:9)

这对我的经历很少有所影响。它可以,但不经常。 查询优化器可以解决这个问题,您无需再次猜测它。

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

一般来说,I would separate JOIN and WHERE conditions for clarity and avoid ambiguities or partial/full cross joins。这个答案仅供参考

注意:问题是“在WHERE差异中加入”但是“JOIN差异中的WHERE”

我会这样做

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进一步细分可读性

答案 1 :(得分:2)

在SQL等声明性语言中,我发现尽可能以声明方式提供帮助,即保持JOIN逻辑(“我如何连接数据?”)与WHERE逻辑分开( “我想过滤掉什么?”)。

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