SUM()比SQL中的SELECT()花费更少的时间。这个怎么运作?

时间:2017-05-17 09:36:30

标签: sql-server select sum execution-time

我有一个包含100万条记录的SQL表。当我打电话

SELECT *
   FROM [AdventureWorksDW2012].[dbo].[LotTable]

完成查询需要13秒。

我运行以下查询以获取ID列的SUM()。它包含包含正负值的随机数。

 SELECT SUM(NewestID)
   FROM LotTable

这个查询花了500毫秒。要执行SUM(),SQL引擎应该读取值并对其应用一些操作。但它如何比SELECT()快速运行。背后的逻辑是什么?请参考下面的图片。提前谢谢。

SELECT() SUM()

3 个答案:

答案 0 :(得分:7)

这是预期的行为。您可以看到,当您向数据库系统发送查询时,会发生以下几种情况:

  • 分析,优化查询并设计执行模式,
  • 执行查询(!),
  • 将结果传达给客户(!)

最后两项(带有感叹号)是加速的潜在来源。

首先,如果总结值,则不需要存储所有这些值。实际上,您使用累加器。因此,成熟的数据库系统将初始化值为0的累加器,然后对于它找到的每一行(匹配可选约束),它会将该值添加到累加器。关键是,累加器使用固定数量的内存。例如,对于整数,通常小于10个字节。因此累加器存储在(快速)存储器中。

SUM(..)的一个优点还在于它是关联的:((a+b)+c)+d等于(a+b)+(c+d)。根据数据库的工作方式和配置方式,它可以在几个工作人员之间分配任务,每个工作人员计算一部分表的总和。然后将这些子项汇总在一起。

另一方面,如果执行SELECT查询,则会逐行写入结果。结果是线性内存使用:对于匹配的每一行,我们需要内存。对于大型表,旧行可能会被“交换”出CPU缓存,有时甚至是内存。因此执行查询需要更长的时间。

最后系统需要响应。现在,如果您执行SUM(..),那只是一行。因此传输的数据量很小。 SELECT查询通常会传输数百行。当然,传输大量数据比花费少量数据需要更多时间。

答案 1 :(得分:3)

简短回答(来自DBA的观点):

这是因为SELECT *必须返回比SELECT SUM(NewestID)更多的列和行。

此外,SUM()可能并行运行,这就是它可能更快的原因。

另外,SSMS中的结果集显示速度很慢,为了比较查询的实际执行时间,您可以在会话开始时使用SET STATISTICS TIME ON。所以,

SET STATISTICS TIME ON

SELECT *
FROM [AdventureWorksDW2012].[dbo].[LotTable]

SELECT SUM(NewestID)
FROM [AdventureWorksDW2012].[dbo].[LotTable]

现在转到Messages标签,查看查询的执行时间:

  • CPU时间:在CPU上进行的操作,如聚合(SUMAVG等)或其他算术运算
  • 经过的时间:CPU时间+存储在RAM中所需的时间,通过内存总线,网络等发送结果。

您可以尝试的另一件事是丢弃SSMS中结果的显示。转到工具 - >选项 - >查询结果 - > SQL Server - >结果到网格并检查"执行后丢弃结果"。

打开一个新标签页并再次运行查询,看看它们的执行时间现在如何比较。 (确保取消选中该选项,以便在新会话的其他选项卡中返回结果)。

实际上,可能会有更多因素,例如,如果您在NewestID列上有索引,或者您在表上有(或没有)聚簇索引。

答案 2 :(得分:-1)

因为您只使用了一个带功能的字段