我有一个包含100万条记录的SQL表。当我打电话
SELECT *
FROM [AdventureWorksDW2012].[dbo].[LotTable]
完成查询需要13秒。
我运行以下查询以获取ID列的SUM()。它包含包含正负值的随机数。
SELECT SUM(NewestID)
FROM LotTable
这个查询花了500毫秒。要执行SUM(),SQL引擎应该读取值并对其应用一些操作。但它如何比SELECT()快速运行。背后的逻辑是什么?请参考下面的图片。提前谢谢。
答案 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
标签,查看查询的执行时间:
SUM
,AVG
等)或其他算术运算您可以尝试的另一件事是丢弃SSMS中结果的显示。转到工具 - >选项 - >查询结果 - > SQL Server - >结果到网格并检查"执行后丢弃结果"。
打开一个新标签页并再次运行查询,看看它们的执行时间现在如何比较。 (确保取消选中该选项,以便在新会话的其他选项卡中返回结果)。
实际上,可能会有更多因素,例如,如果您在NewestID
列上有索引,或者您在表上有(或没有)聚簇索引。
答案 2 :(得分:-1)
因为您只使用了一个带功能的字段