我有一个包含任务和便笺两个表,并希望检索与对每一个相关联的音符数的任务列表。 这两个查询做的工作:
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()等。
因为它是被用于在外部查询的每一行执行的子查询速度会变慢。 在加入会更快,因为它是做一次。 我相信,查询优化器将无法改写这个查询计划,因为它不能识别的等价性。
通常你会为这个分类数量做一个联接和GROUP BY。 你看那种相关子查询主要的兴趣,如果他们必须做一些分组或更复杂的谓词未参与了另一个连接的表。
如果您使用SQL Server Management Studio中,您可以输入两个版本进入查询编辑器,然后单击鼠标右键,然后选择显示估计的执行计划。 它会给你相对于一批两个百分点的成本。 如果他们希望采取同样的时间,他们都会显示为50% - 在这种情况下,自由选择你喜欢的其他原因(更易于阅读,维护更方便,更好地适应您的编码标准等)。 否则,你可以挑一个相对于该批次的百分比较低的成本。
您可以使用相同的技术来看待改变任何查询,通过比较两个版本的做同样的事情来提高性能。
当然,因为它是相对于该批次成本,这并不意味着,要么查询一样快,因为它可能是 - 它只是告诉你他们如何互相比较,而不是一些名义上的最佳查询得到同样的结果。
有没有这方面的明确的答案。 您应该查看SQL计划。 在关系代数方面,他们基本上是相等的。
我使它成为一个点,以避免子查询尽可能。 联接通常会更有效率。
您可以使用,而且它们具有相同的语义。 在一般情况下,经验法则是用哪个形式更容易让你阅读,除非性能是一个问题。
如果性能是一个问题,然后使用其他形式的重写查询实验。 有时,优化器将使用索引的一种形式,而不是其他。