在SQL Server中连接两个表时,检查复合键的一部分的位置是否重要?

时间:2010-08-24 15:46:31

标签: sql sql-server performance

我在一个复合键上加入了两个表,我想知道在我进行连接时比较相应列的位置是否重要。

假设我有一个TableA表,包含ColAFoo,ColAFoo2和ColABar列。 TableA具有包含ColAFoo和ColAFoo2(PK_TableA)的复合主键。

我还有TableB,ColBFoo,ColBFoo2和ColBOther。 TableB的列ColBFoo和ColBFoo2包含TableA主键的外键(FK_TableA_TableB)。

我需要在密钥上加入两个表。在表现方面,以下三个(非常人为的)陈述之间是否存在差异?

SELECT *
  FROM TableA a
  JOIN TableB b
    ON  a.ColAFoo = b.ColBFoo
        AND a.ColAFoo2 = b.ColBFoo2

SELECT *
  FROM TableA a
  JOIN TableB b
    ON  a.ColAFoo = b.ColBFoo
  WHERE a.ColAFoo2 = b.ColBFoo2

-- this one is a little /too/ contrived, apparently (see comments)
SELECT *
  FROM TableA a
  JOIN TableB b
  WHERE a.ColAFoo = b.ColBFoo
        AND a.ColAFoo2 = b.ColBFoo2

6 个答案:

答案 0 :(得分:5)

对于inner join,以下结果是公平的,并且可能会产生相同的查询计划:

SELECT *
  FROM TableA a
  JOIN TableB b
    ON  a.ColAFoo = b.ColBFoo
        AND a.ColAFoo2 = b.ColBFoo2

SELECT *
  FROM TableA a
  JOIN TableB b
    ON  a.ColAFoo = b.ColBFoo
  WHERE a.ColAFoo2 = b.ColBFoo2

-- SQL89 inner join:
SELECT *
  FROM TableA a, TableB b
 WHERE a.ColAFoo = b.ColBFoo
       AND a.ColAFoo2 = b.ColBFoo2

然而将连接条件放在ON子句中会与其他程序员沟通,“嘿!这是将表关联起来的标准。”与where子句中的内容相对应,即“在连接完成后限制结果的条件。”

此外,在使用outer join时,标准的位置会对结果产生很大的影响,因此在所有情况下都可以将连接标准放在on中。

答案 1 :(得分:0)

如果你只有一个INNER JOIN,那么3都是一样的。
对于左/右连接它们是完全不同的。

答案 2 :(得分:0)

没有区别。优化器将以相同的方式解析它们。我个人的偏好是你的第一个例子。

SELECT *
  FROM TableA a
    JOIN TableB b
      ON  a.ColAFoo = b.ColBFoo
        AND a.ColAFoo2 = b.ColBFoo2

答案 3 :(得分:0)

理论上,第一种方式是最好的:

SELECT *
  FROM TableA a
  JOIN TableB b
    ON  a.ColAFoo = b.ColBFoo
        AND a.ColAFoo2 = b.ColBFoo2

因为你指定了TableA和amp;之间的关系。 TableB可能有助于优化器。在实践中,数据库已经知道(特别是如果你建立了外键关系),所以它确实没关系。

答案 4 :(得分:0)

如果是2个表,则没关系。如果您连接多个表,请不要忘记在连接后处理where子句,因此如果您过滤记录可能会在性能上有显着差异,可以在ON INNER JOIN部分中对其进行过滤,在WHERE。

答案 5 :(得分:0)

对于你的设计版本,不管它没关系。但我肯定已经看到了有额外的JOIN或WHERE子句。