2010-08-24 47 views
1

我在组合键上连接两个表,我想知道在我进行连接时比较相应的列是否很重要。在SQL Server中连接两个表时,检查组合键的一部分时重要吗?

假设我有一个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
         
  
+3

第三个选项是否实际在SQL Server上运行?我认为'on'是'join'关键字所必需的。 (除了'交叉连接'的情况,但我没有SQL Server方便测试 – 2010-08-24 15:58:18

+0

@ Shannon:同意最后一个例子应该写成:'SELECT * FROM TableA a,TableB b WHERE a .ColAFoo = b.ColBFoo AND a.ColAFoo2 = b.ColBFoo2' – 2010-08-24 16:09:34

+0

好的。:)我会相应地更新问题文本。 – stack 2010-08-24 16:59:40

回答

5

对于inner join在结果equivelent以下,并可能会产生相同的查询计划:

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是一个好习惯。

0

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

0

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

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

从理论上讲,第一种方法是最好的:

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

如要指定这可能有助于优化表A表B &之间的关系。在实践中,数据库已经知道(特别是如果你建立了外键关系),所以它确实没关系。

0

在2个表格的情况下并不重要。如果加入多个表,请不要忘记where子句在连接之后进行处理,因此如果筛选记录可能会在性能上产生显着差异,这些记录可以在INNER JOINON部分的WHERE中过滤。

+0

在连接之后处理where子句,**逻辑**。只要结果是相同的,优化程序就可以重新排列操作顺序。 – 2010-09-24 19:12:13

+0

当然,它可能,而且它肯定会在简单情况下做到。但有时候它不会,所以我认为最好将连接条件保存在'JOIN'节中,而不是'WHERE'中。另外,阅读这些查询更容易。 – a1ex07 2010-09-24 19:45:34

0

对于你设计的版本,没有关系。但是我肯定看到有更多的JOIN或WHERE子句。

相关问题