2012-09-24 2 views
1

많은 수의 게이지에 대해 5 분 간격으로 데이터 판독 값을 저장합니다. 참여누적 합계가 느린 SQL 쿼리

데이터 테이블은 다음과 같습니다

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 

어떤 방법으로 테이블 구조를 변경하지 않고, 무엇을 복사하는 가장 효율적인 방법 및 GaugeSummaryData에 GaugeData에서 집계 데이터는 것입니까?

나는이 두 가지 방법을 이미 시도해 보았습니다. 커서를 사용하면 GaugeData에서 GaugeSummaryData로 모든 데이터를 복사하는 데 40 분이 소요됩니다. 삽입/업데이트 문 사용에는 2 시간 이상이 걸렸습니다.

누군가 가장 효율적인 방법을 제안 해주세요. 가짜 코드 또는 SQL은 높이 평가했다.

+0

얼마나 많은 데이터가 있습니까? 10MB? 100GB? –

+0

약 5GB – user1634569

+0

SQL 프로파일 러를 사용하여 쿼리의 어느 부분이 가장 많은 시간을 사용하고 있는지 확인한 적이 있습니까? –

답변

0

GaugeSummaryData를 매일 한 번만 업데이트해야합니까? 그렇지 않으면 게이지 데이터에 삽입 후 트리거를 적용하는 것이 전체 프로세스를 실시간으로하고 시간을 덜 소요시켜야합니다. 게이지 데이터에 항목이 작성되면 트리거는 GaugeSummaryData에서 해당 항목을 업데이트합니다. 해당 날짜의 첫 번째 항목 인 경우 트리거는 업데이트하기 전에 Day Total을 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