简体   繁体   English

在SQL Server中联接两个表时,在哪里检查组合键的一部分有关系吗?

[英]Does it matter where I check part of a composite key when joining two tables in SQL Server?

I'm joining two tables on a composite key, and I'm wondering if it matters where I compare the corresponding columns when I do the join. 我要在一个组合键上连接两个表,并且想知道在进行连接时比较相应列的位置是否重要。

Say I have a table, TableA, with columns ColAFoo, ColAFoo2, and ColABar. 假设我有一个表TableA,其中包含列ColAFoo,ColAFoo2和ColABar。 TableA has a composite primary key comprising ColAFoo and ColAFoo2 (PK_TableA). TableA具有包含ColAFoo和ColAFoo2(PK_TableA)的复合主键。

I also have TableB, with ColBFoo, ColBFoo2, and ColBOther. 我也有TableB,以及ColBFoo,ColBFoo2和ColBOther。 TableB's columns ColBFoo and ColBFoo2 comprise a foreign key to TableA's primary key (FK_TableA_TableB). TableB的列ColBFoo和ColBFoo2构成了TableA的主键(FK_TableA_TableB)的外键。

I need to join the two tables on the key. 我需要将两个表连接到键上。 Is there a difference between the following three (extraordinarily contrived) statements in terms of performance? 在性能方面,以下三个(特别是人为)语句之间有区别吗?

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
 

 
 
 

For an inner join the following are equivelent in results, and will probably produce the same query plan: 对于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

However Putting the join criteria in the ON clause will communicate to other programmers, "Hey! This is the criteria to relate the tables together." 但是,将连接条件放在ON子句中将与其他程序员交流,“嘿!这是将表关联在一起的条件。” Versus stuff in the where clause that is, "criteria to limit the results, after the joins are done." 与where子句中的内容相对,即“连接完成后限制结果的标准”。

Also, the placement of the criteria makes a big difference in results when using an outer join , so it is a good habit to get into to put the join criteria in the on in all cases. 另外,使用outer join ,条件的放置在结果上有很大的不同,因此在所有情况下都应将联接条件置于on

if you have only an INNER JOIN then the 3 are all the same. 如果您只有一个INNER JOIN,则3个都相同。
for LEFT/RIGHT joins they are quite different. 对于LEFT / RIGHT连接,它们是完全不同的。

It makes no difference. 这没什么区别。 The optimizer will parse them all the same way. 优化器将以相同的方式解析它们。 My personal preference would be your first example. 我的个人喜好将是您的第一个例子。

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

In theory, the first way is best: 从理论上讲,第一种方法是最好的:

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

as you are specifying the relationship between TableA & TableB which might help the optimizer. 当您指定TableA和TableB之间的关系时,这可能对优化程序有所帮​​助。 In practice, the database already knows that (especially if you have a foreign key relationship established), so it really doesn't matter. 实际上,数据库已经知道这一点(特别是如果您已建立外键关系),因此这实际上并不重要。

In case of 2 tables it doesn't matter. 如果有2张桌子,那没关系。 If you join many tables, don't forget that where clause is processed after joins, so you may have a significant difference in performance if you filter records, which can be filtered in ON section of INNER JOIN , in WHERE. 如果您联接许多表,请不要忘记联接后要处理where子句,因此,如果您过滤记录(可以在WHERE的INNER JOIN ON部分中进行过滤),则性能可能会有显着差异。

For your contrived version, no it won't matter. 对于人为设计的版本,没有关系。 But I've definitely seen when there's additional JOIN or WHERE clauses. 但是,我绝对可以看到是否还有其他JOIN或WHERE子句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM