【发布时间】:2013-09-16 20:52:00
【问题描述】:
我需要在当前有超过 400k 行并准备进一步增长的表上计算截至指定日期的列总数。我发现 SUM() 聚合函数对于我的目的来说太慢了,因为对于超过 50k 行的总和,我无法获得超过 1500 毫秒的速度。
请注意,下面的代码是迄今为止我发现的最快的实现。值得注意的是,从CustRapport 过滤数据并将其存储在临时表中,使我的性能提高了 3 倍。我也尝试过索引,但它们通常会使它变慢。
然而,我希望该函数至少快一个数量级。关于如何实现这一目标的任何想法?我偶然发现了http://en.wikipedia.org/wiki/Fenwick_tree。但是,我宁愿在 SQL Server 中处理存储和计算。
CustRapport 和 CustLeistung 是具有以下定义的视图:
ALTER VIEW [dbo].[CustLeistung] AS
SELECT TblLeistung.* FROM TblLeistung
WHERE WebKundeID IN (SELECT WebID FROM XBauAdmin.dbo.CustKunde)
ALTER VIEW [dbo].[CustRapport] AS
SELECT MainRapport.* FROM MainRapport
WHERE WebKundeID IN (SELECT WebID FROM XBauAdmin.dbo.CustKunde)
感谢您的帮助或建议!
ALTER FUNCTION [dbo].[getBaustellenstunden]
(
@baustelleID int,
@datum date
)
RETURNS
@ret TABLE
(
Summe float
)
AS
BEGIN
declare @rapport table
(
id int null
)
INSERT INTO @rapport select WebSourceID from CustRapport
WHERE RapportBaustelleID = @baustelleID AND RapportDatum <= @datum
INSERT INTO @ret
SELECT SUM(LeistungArbeit)
FROM CustLeistung INNER JOIN @rapport as r ON LeistungRapportID = r.id
WHERE LeistungArbeit is not null
AND LeistungInventarID is null AND LeistungArbeit > 0
RETURN
END
执行计划:
【问题讨论】:
-
请添加您在表 CustLeistung 和 CustRapport 上的索引。另外,您在表变量中插入了多少条记录?
-
RapportDatum的数据类型是什么?是date吗?即没有时间分量? -
RapportDatum是datetime -
请提供函数
Portal_common_MyKundeUser的定义,因为它似乎在此处弄乱了优化器。CusteKunde似乎也是一个视图,所以我们也需要这个定义。 -
对于今天仍然来这里的人:this post 从 2012 年指向
SUM()+OVER()+ROWS作为一种非常快速的方法
标签: sql performance sql-server-2008 sum aggregate-functions