你写的是哪个SQL?

时间:2009-08-05 16:27:22

标签: tsql join conditional where-clause

当连接两个表时,下面两个块之间有什么区别,哪个是更好的方法?

模式A:

SELECT ...
FROM A
    INNER JOIN B
        ON A.PK = B.FK
WHERE 1=1
    AND A.Name = "Foo"
    AND B.Title = "Bar"

模式B:

SELECT ...
FROM A
    INNER JOIN B
        ON A.PK = B.FK
            AND B.Title = "Bar"
WHERE 1=1
    AND A.Name = "Foo"

4 个答案:

答案 0 :(得分:13)

这种情况因人而异,但我认为模式A更好。

它的作用是将表级连接与过滤器分开。这对于具有多个连接和多个过滤器的查询很有用,因为它清楚地区分了正在进行的两种类型的连接。

答案 1 :(得分:4)

我更喜欢模式A,但可能没有任何区别。你真的必须看看执行计划,以确保它有效运行。

答案 2 :(得分:3)

如果您将INNER JOIN替换为OUTER JOIN,则会有所不同。

否则,这些查询:

SELECT  ...
FROM    A
INNER JOIN
        B
ON      A.PK = B.FK
WHERE   A.Name = "Foo"
        AND B.Title = "Bar"

SELECT  ...
FROM    A
INNER JOIN
        B
ON      A.PK = B.FK
        AND B.Title = "Bar"
WHERE   A.Name = "Foo"

SELECT  *
FROM    A, B
WHERE   B.Title = "Bar"
        AND A.Name = "Foo"
        AND A.PK = B.FK

是完全相同的。

OracleMySQLPostgeSQLSQL Server会将它们完全相同,并对所有这些使用完全相同的计划。

我会用这个:

SELECT  ...
FROM    A
INNER JOIN
        B
ON      B.FK = A.PK
WHERE   A.Name = "Foo"
        AND B.Title = "Bar"

如果B.FK上有一个单列密钥,那么这个:

SELECT  ...
FROM    A
INNER JOIN
        B
ON      B.FK = A.PK
        AND B.Title = "Bar"
WHERE   A.Name = "Foo"

如果(B.FK, B.title)上有复合键。

在这种情况下,连接条件更直观。

答案 3 :(得分:0)

我可能错了,但我认为第一种方法更有效率。您的查询从里到外执行。因此,当你首先运行你的连接时,它会运行得更快,因为它必须匹配(可能是索引的)PK& FK Fields而不是像Title字段那样无关紧要(可能是varchar,使得匹配更慢)。因此,当您到达filtering where子句时,您可以使用较少的数据来执行匹配。但总的猜测。我想知道其他人会怎么说。看到这个执行计划不会有害:)