编码内连接的两种方法中哪一种更快?

Lil*_*sey 6 t-sql sql-server join sql-server-2005

我更喜欢使用实际上是内联连接的t-sql代码,而不是在存储过程或视图的末尾有一个很长的连接列表.

例如,我代码:

SELECT      PKey  ,    Billable, 
    (SELECT LastName  FROM Contact.dbo.Contacts WHERE (Pkey = Contacts_PKey)),
    (SELECT Description FROM Common.dbo.LMain WHERE (PKey= DType)),  
    (SELECT  TaskName  FROM  Common.dbo.LTask WHERE  (PKey =  TaskType)) ,  
    StartTime,  EndTime,  SavedTime
FROM   dbo.TopicLog   where  StartTime > '7/9/09'  ORDER BY  StartTime
Run Code Online (Sandbox Code Playgroud)

而不是

SELECT t.PKey, t.Billable, c.LastName, m.Description, lt.TaskName, t.StartTime, t.EndTime, t.SavedTime
FROM dbo.TopicLog AS t     
inner join  Contact.dbo.Contacts as c   on  c.Pkey = t.Contacts_PKey and t.StartTime > '7/9/09'
inner join  Common.dbo.LMain  as m  on  m.PKey = t.DType
inner join  Common.dbo.LTask  as lt on lt.PKey = t.TaskType
ORDER BY t.StartTime
Run Code Online (Sandbox Code Playgroud)

我更喜欢这种类型的语法,因为它在编写或调试时不那么容易混淆,特别是当有许多表被连接或正在进行其他事情时(case语句,t-sql函数,自联接等)

但我的问题是 - 通过这种方式查询数据库,性能受到了打击.

我还没有收集足够的数据来衡量差异,但我会在某个时候继续前进.

在进一步讨论之前,我想先了解一下.我不希望以后再回去重新编码所有内容以提高性能.

Eri*_*ric 20

通常是第二个(实际的内连接).第一个(子查询)为每一行执行3次查询,但这通常由编译器管理,以便减少差异.

最好的:自己检查查询执行计划!

由于你的性能很慢,我的猜测是你的表没有正确编入索引.您应该在所有主键上使用聚簇索引,在外键上使用非聚簇索引(用于进行连接的索引).

我应该注意,当且仅当您在所有连接条件中具有匹配值时,这两个查询是等效的(即 - 始终返回主表中的所有行).否则,null如果没有匹配,您将从子查询中获取.内部联接会主动过滤掉与连接条件不匹配的任何行.子查询方法实际上与左外连接等效(在结果中,而不是速度或执行).

  • +1"自己检查查询执行计划!" 这是唯一可以确定的方法.优化器*可能会*自动将它们转换为JOIN.虽然,这两个查询并不完全相同.#1是LEFT JOIN,#2是INNER JOIN.所以无论如何他们会给你不同的计划. (2认同)

Wil*_*rds 10

第一种方法根本不是内连接,它是一个相关的子查询.并且它们更像是左外连接而不是内连接,因为当没有匹配值时它们将返回NULL.