SQL查询缓慢计算累计总数

时间:2012-09-24 03:28:43

标签: sql sql-server performance

我们以5分钟的间隔存储大量仪表的数据读数。

所涉及的数据表是:

Table1 - GaugeData
Columns - 
    GaugeID (int, primary key)
    Timestamp (datetime, primary key)
    Value (decimal)

Table2 - GaugeSummaryData
Columns - 
    GaugeID (int, primary key)
    DayTimestamp (date, primary key)
    DayTotal (decimal) - total for the current date/day
    CumulativeTotal (decimal) - total up to and including the current date

如果不以任何方式更改表结构,将GaugeData中的数据复制和聚合到GaugeSummaryData中的最有效方法是什么?

我已经尝试过这两种方式了。使用游标需要40分钟将所有数据从GaugeData复制到GaugeSummaryData。使用插入/更新语句需要2小时+。

有人可以建议最有效的方法吗?伪代码或SQL赞赏。

2 个答案:

答案 0 :(得分:1)

5GB并不是那么多数据。我会说你的表可以使用一些新的索引。一旦这些就绪,插入触发器应该非常好地完成工作。

CREATE TRIGGER trig_INS_GaugeData ON GaugeData FOR INSERT AFTER
AS
BEGIN
    -- create new GaugeSummaryData rows for dates that are not in table yet
    INSERT GaugeSummaryData (GaugeID, DayTimestamp, DayTotal, CumulativeTotal)
    SELECT I.GaugeID, CONVERT(date, I.TimeStamp), 0, SUM(GT.DayTotal)
    FROM INSERTED AS I
    INNER JOIN GaugeSummaryData GT ON I.GaugeID = GT.GaugeID AND convert(date, I.TimeStamp) < GT.DayTimestamp
    GROUP BY I.GaugeID, convert(date, I.TimeStamp)
    -- update GaugeSummaryData rows with totals
    UPDATE GSD
    SET DayTotal = DayTotal+I.Value, CumulativeTotal = CumulativeTotal + I.Value
    From INSERTED AS I
    INNER JOIN GaugeSummaryData GT ON I.GaugeID = GT.GaugeID
          and convert(date, I.TimeStamp) = GT.DayTimestamp
END

答案 1 :(得分:0)

是否有必要在每天结束时更新GaugeSummaryData一次?如果不是,则可能在Gauge Data上应用后插入触发器应该使整个过程实时且耗时更少。只要在Gauge Data中输入一个条目,触发器就会更新GaugeSummaryData中的相应条目。如果它是当天的第一个条目,那么触发器应该在更新前将Day Total重置为0.