的Transact-SQL - 子查询或左加入?(Transact-SQL - sub query

2019-07-30 19:13发布

我有一个包含任务和便笺两个表,并希望检索与对每一个相关联的音符数的任务列表。 这两个查询做的工作:

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

他们之间有一个区别,我应该使用了另一种,或者是他们只是在做同样的工作的两个方面? 谢谢。

Answer 1:

在小的数据集他们洗,当涉及到性能。 当索引,该LOJ好一点。

我对大数据集是一个内部联接中(内部联接将工作太)将通过一个非常大的因素(对不起,没有数字)跑赢子查询。



Answer 2:

在大多数情况下,优化器将对待他们一样。

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

此外,第二语法是更灵活的,如果有进一步的聚集体,其可能会在将来,除了被加入到COUNT,像MIN(some_scalar),MAX(),AVG()等。



Answer 3:

因为它是被用于在外部查询的每一行执行的子查询速度会变慢。 在加入会更快,因为它是做一次。 我相信,查询优化器将无法改写这个查询计划,因为它不能识别的等价性。

通常你会为这个分类数量做一个联接和GROUP BY。 你看那种相关子查询主要的兴趣,如果他们必须做一些分组或更复杂的谓词未参与了另一个连接的表。



Answer 4:

如果您使用SQL Server Management Studio中,您可以输入两个版本进入查询编辑器,然后单击鼠标右键,然后选择显示估计的执行计划。 它会给你相对于一批两个百分点的成本。 如果他们希望采取同样的时间,他们都会显示为50% - 在这种情况下,自由选择你喜欢的其他原因(更易于阅读,维护更方便,更好地适应您的编码标准等)。 否则,你可以挑一个相对于该批次的百分比较低的成本。

您可以使用相同的技术来看待改变任何查询,通过比较两个版本的做同样的事情来提高性能。

当然,因为它是相对于该批次成本,这并不意味着,要么查询一样快,因为它可能是 - 它只是告诉你他们如何互相比较,而不是一些名义上的最佳查询得到同样的结果。



Answer 5:

有没有这方面的明确的答案。 您应该查看SQL计划。 在关系代数方面,他们基本上是相等的。



Answer 6:

我使它成为一个点,以避免子查询尽可能。 联接通常会更有效率。



Answer 7:

您可以使用,而且它们具有相同的语义。 在一般情况下,经验法则是用哪个形式更容易让你阅读,除非性能是一个问题。

如果性能是一个问题,然后使用其他形式的重写查询实验。 有时,优化器将使用索引的一种形式,而不是其他。



文章来源: Transact-SQL - sub query or left-join?
标签: sql tsql