使用exists子句加入或关联子查询,哪个更好

时间:2010-07-22 05:02:05

标签: sql

select * 
from ContactInformation c 
where exists (select * from Department d where d.Id = c.DepartmentId )

select * 
from ContactInformation c 
inner join Department d on c.DepartmentId = d.Id  

这两个查询都给出了相同的输出,这对于性能明智的连接或与exists子句相关的子查询是好的,哪一个更好。

编辑: - 有连接的alternet方式,以提高性能: - 在上面的2个查询中,我想要来自dept以及contactinformation表的信息

4 个答案:

答案 0 :(得分:5)

通常,EXISTS子句因为您可能需要DISTINCT来为JOIN提供预期输出。例如,如果Department行有多个ContactInformation行。

在上面的示例中,SELECT *

  • 也意味着不同的输出,因此它们实际上并不等同
  • 使用索引的可能性较小,因为您要删除所有列

即使列表列表有限,他们也会给出相同的计划:直到你需要DISTINCT ......这就是为什么我说“EXISTS”

答案 1 :(得分:4)

你需要衡量和比较 - 没有一个更好的黄金法则 - 它取决于你系统中的太多变量和事物。

在SQL Server Management Studio中,您可以将两个查询放在一个窗口中,从“查询”菜单中选择Include actual execution plan,然后一起运行它们。

alt text http://i31.tinypic.com/2rw48s2.png

您应该比较他们的执行计划和在一个或另一个查询上花费了多少时间的百分比。最有可能的是,在这种情况下,两者都接近50%。如果不是 - 那么你知道两个查询中哪一个表现得更好。

您可以从Simple-Talk了解有关SQL Server执行计划(甚至下载免费电子书)的更多信息 - 强烈推荐。

答案 2 :(得分:2)

我假设您要么在第二个查询中将DISTINCT关键字添加到SELECT子句中(或者,部门只有一个联系人的可能性较小)。

首先,始终以“逻辑”考虑开始。 EXISTS构造可以说更直观,因此,所有“物理”都是平等的,我会选择它。

其次,有一天您将需要移植此代码,而不一定需要移植到不同的SQL产品,但是,相同的产品,但使用不同的优化器。一个不错的优化器应该认识到两者都是等价的并且提出了相同的理想计划。从理论上讲,考虑到EXISTS结构的短路可能性稍大。

第三,使用相当大的数据集进行测试。如果性能不可接受,请开始考虑“物理”考虑因素(但我建议您在完美优化器到来时的评论中始终保留您的'逻辑纯'代码:)

答案 3 :(得分:1)

您的第一个查询应该输出Department列,而第二个查询不应该。

如果您只对ContactInformation感兴趣,则这些查询是等效的。您可以同时运行它们并检查查询执行计划以查看哪一个运行得更快。例如,在MYSQL上,where exists对于可空列更有效,而inner join如果两列都不可为空则表现更好。