5

所以我知道在查询的 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 会怎样?这不会使查询更有效率吗?我知道有时两种方法的结果可能不同,但我不知道为什么?

谢谢。

4

2 回答 2

9

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

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

一般来说,为了清楚起见,我会分开 JOIN 和 WHERE 条件,并避免歧义或部分/完全交叉连接。此答案仅供参考

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

我会这样做

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 来进一步分解它以提高可读性

于 2013-05-15T14:18:15.807 回答
2

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

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

于 2013-05-15T14:18:01.633 回答