我需要在当前有超过 40 万行并且准备进一步增长的表上计算到指定日期的总列数。我发现 SUM() 聚合函数对于我的目的来说太慢了,因为对于超过 50k 行的总和,我无法使其速度超过大约 1500 毫秒。

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

但是,我希望该函数至少快一个数量级。关于如何实现这一目标的任何想法?我偶然发现了 http://en.wikipedia.org/wiki/Fenwick_tree 。但是,我更愿意在 SQL Server 中处理存储和计算。
CustRapportCustLeistung 是具有以下定义的 View :

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

最佳答案

在您提供更多信息之前,我现在可以提供一般建议。

更新了我的查询,因为它是从 View 中提取直接从表中提取的。

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
  • 去掉表变量。它们有其用途,但是当我获得超过 100 条记录时,我会切换到临时表;根据我的经验,索引临时表的性能更好。
  • 将您的选择更新为上述查询并重新测试性能
  • 检查并确保查询中的每个列引用都有索引。如果您使用显示实际执行计划,SQL Server 将帮助确定索引有用的地方。
  • 关于sql - 快速计算大型 SQL Server 表的部分总和,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18764767/

    10-11 22:26
    查看更多