繁体   English   中英

Transact-SQL - 子查询还是左连接?

[英]Transact-SQL - sub query or left-join?

我有两个包含任务和注释的表,并希望检索一个任务列表,其中包含每个任务和相关注释的数量。 这两个查询完成了这项工作:

select t.TaskId,
       (select count(n.TaskNoteId) from TaskNote n where n.TaskId = t.TaskId) 'Notes'
from   Task t

-- or
select t.TaskId,
       count(n.TaskNoteId) 'Notes'
from   Task t
left join
       TaskNote n
on     t.TaskId = n.TaskId
group by t.TaskId

它们之间是否存在差异,我应该使用其中一个,还是仅仅是两种方式做同样的工作? 谢谢。

在小型数据集上,它们在性能方面是清洗的。 索引时,LOJ稍好一些。

我在大型数据集上发现内部连接(内部连接也可以工作)会超出子查询的一个非常大的因素(对不起,没有数字)。

在大多数情况下,优化器会对它们进行相同的处理。

我倾向于选择第二种,因为它具有较少的嵌套,这使得它更容易阅读和更容易维护。 出于同样的原因,我已经开始使用SQL Server的公用表表达式来减少嵌套。

此外,如果还有其他聚合,除了COUNT之外可以在将来添加聚合,如MIN(some_scalar),MAX(),AVG()等,第二种语法更灵活。

子查询将在外部查询中的每一行执行时变慢。 一旦完成,连接将更快。 我相信查询优化器不会重写此查询计划,因为它无法识别等效性。

通常你会为这种计数进行连接和分组。 如果必须在未参与另一个连接的表上执行某些分组或更复杂的谓词,则您显示的排序的相关子查询主要是有意义的。

如果您使用的是SQL Server Management Studio,则可以在查询编辑器中输入两个版本,然后右键单击并选择“显示估计执行计划”。 它将为您提供相对于批次的两个百分比成本。 如果他们预计会花费相同的时间,他们都会显示为50% - 在这种情况下,选择您喜欢的其他原因(更容易阅读,更容易维护,更符合您的编码标准等)。 否则,您可以选择相对于批次的百分比成本较低的那个。

您可以使用相同的技术来查看更改任何查询以通过比较执行相同操作的两个版本来提高性能。

当然,因为它是相对于批处理的成本,它并不意味着任何一个查询都尽可能快 - 它只是告诉你它们如何相互比较,而不是一些概念上的最佳查询来获得相同的结果。

对此没有明确的答案。 您应该查看SQL计划。 就关系代数而言,它们基本上是等价的。

我尽可能避免使用子查询。 加入通常会更有效率。

您可以使用其中任何一个,它们在语义上是相同的。 一般来说,经验法则是使用更容易阅读的形式,除非性能是一个问题。

如果性能是一个问题,那么尝试使用其他表单重写查询。 有时,优化器将使用一个表单的索引,而不是另一个表单。

暂无
暂无

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

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