快速计算大型SQL Server表上的部分和

时间:2013-09-12 12:48:41

标签: sql performance sql-server-2008 sum aggregate-functions

我需要在目前有超过400k行的表上计算一个列到指定日期的总计,并准备进一步增长。我发现SUM()聚合函数对于我的目的来说太慢了,因为对于超过50k行的总和,我的速度不能超过1500ms。

请注意,以下代码是迄今为止我发现的最快的代码。值得注意的是,从CustRapport过滤数据并将其存储在临时表中,使我的性能提高了3倍。我也尝试过索引,但它们通常会变慢。

然而,我希望这个功能至少快一个数量级。有关如何实现这一点的任何想法?我偶然发现了http://en.wikipedia.org/wiki/Fenwick_tree。但是,我宁愿在SQL Server中处理存储和计算。

CustRapportCustLeistung是具有以下定义的视图:

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

执行计划:

http://s23.postimg.org/mxq9ktudn/execplan1.png

http://s23.postimg.org/doo3aplhn/execplan2.png

1 个答案:

答案 0 :(得分:1)

我可以提供一般性建议,直到您提供更多信息。

更新了我的查询,因为它是从视图中拉出来直接从表中拉出来的。

INSERT INTO @ret
    SELECT
        SUM(LeistungArbeit)
    FROM (
        SELECT DISTINCT WebID FROM XBauAdmin.dbo.CustKunde
    ) Web
    INNER JOIN dbo.TblLeistung ON TblLeistung.WebKundeID=web.webID
    INNER JOIN dbo.MainRapport ON MainRapport.WebKundeID=web.webID 
        AND TblLeistung.LeistungRapportID=MainRapport.WebSourceID
        AND MainRapport.RapportBaustelleID = @baustelleID
        AND MainRapport.RapportDatum <= @datum
   WHERE TblLeistung.LeistungArbeit is not null 
   AND TblLeistung.LeistungInventarID is null
   AND TblLeistung.LeistungArbeit > 0
  1. 摆脱表变量。他们有自己的用途,但是当我获得100条记录时,我会切换到临时表;索引临时表在我的经验中表现得更好。
  2. 将您的选择更新为上述查询并重新测试效果
  3. 检查并确保查询中的每个列引用都有索引。如果使用show实际执行计划,SQL Server将帮助确定索引在哪里有用。