我正在努力调整一些聚合重量级的查询,并且我想知道重复使用相同的聚合函数是否会显着降低性能。
我假设MS SQL Server足够智能,只能计算每次重复聚合一次,然后每次在同一查询中遇到完全聚合时重用结果值 - 我的假设在这里是否正确?
替代方案是,我们可以在这个视图中添加更多连接(一遍又一遍地连接相同的表),使用不同的join on
子句,以一系列不同的方式将行组合在一起生成各种总计而不重复使用任何聚合函数 - 但是看一下执行计划,我们可以看到添加更多联接肯定确实使查询需要更长时间,并且我们在技术上已经掌握了所有信息无论如何都需要当前的连接数(我们只需执行添加即可生成复合总数)。
这是一个示例代码,来自其中一个视图:
COUNT_BIG ( [UVCE]. [ID] ) AS [TotalU] ,
COUNT_BIG ( [SVCE]. [ID] ) AS [TotalS] ,
COUNT_BIG ( [TVCE]. [ID] ) AS [TotalT] ,
COUNT_BIG ( [CVCE]. [ID] ) AS [TotalC] ,
COUNT_BIG ( [WVCE]. [ID] ) AS [TotalW] ,
/* More individual totals, etc. */
COUNT_BIG ( [SCE]. [ID] ) +
COUNT_BIG ( [TCE]. [ID] ) +
COUNT_BIG ( [CCE]. [ID] ) +
COUNT_BIG ( [WCE]. [ID] ) +
COUNT_BIG ( [UVCE]. [ID] ) +
COUNT_BIG ( [SVCE]. [ID] ) +
COUNT_BIG ( [TVCE]. [ID] ) +
COUNT_BIG ( [CVCE]. [ID] ) +
COUNT_BIG ( [WVCE]. [ID] ) AS [OverallTotal] ,
CASE WHEN COUNT_BIG ( [SCE]. [ID] ) +
COUNT_BIG ( [TCE]. [ID] ) +
COUNT_BIG ( [CCE]. [ID] ) +
COUNT_BIG ( [WCE]. [ID] ) +
COUNT_BIG ( [UVCE]. [ID] ) +
COUNT_BIG ( [SVCE]. [ID] ) +
COUNT_BIG ( [TVCE]. [ID] ) +
COUNT_BIG ( [CVCE]. [ID] ) +
COUNT_BIG ( [WVCE]. [ID] ) >= 64 THEN 4E0 ELSE (
COUNT_BIG ( [SCE]. [ID] ) +
COUNT_BIG ( [TCE]. [ID] ) +
COUNT_BIG ( [CCE]. [ID] ) +
COUNT_BIG ( [WCE]. [ID] ) +
COUNT_BIG ( [UVCE]. [ID] ) +
COUNT_BIG ( [SVCE]. [ID] ) +
COUNT_BIG ( [TVCE]. [ID] ) +
COUNT_BIG ( [CVCE]. [ID] ) +
COUNT_BIG ( [WVCE]. [ID] ) )
/ ( 64 / 4E0 ) END AS [Score]
答案 0 :(得分:1)
SQL Server优化器非常好。
但是,在使用聚合函数时,您忽略了一个重要的观点。通常,group by
子句比聚合函数调用更昂贵。也就是说,移动数据来定义组是查询的昂贵部分。 (一个例外是count(distinct)
。)
也就是说,做几十个函数调用会对性能产生明显的影响。在SQL Server中,使用公共表表达式(CTE)或子查询在一个级别定义值并在另一个级别使用它们很容易。也就是说,SQL Server可能会为您执行此操作。我只是认为查询的其他部分在性能方面可能更重要。