4

我需要在当前有超过 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

执行计划:

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

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

4

1 回答 1

1

General advice I can provide now until you provide more information.

Updated my query since it was pulling from views to pull straight from the tables.

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. Get rid of the table variable. They have their use, but I switch to temp tables when I get over a 100 records; indexed temp tables simply perform better in my experience.
  2. Update your select to the above query and retest performance
  3. Check and ensure there are indexes on every column references in the query. If you use the show actual execution plan, SQL Server will help identify where indexes would be useful.
于 2013-09-12T13:02:47.277 回答