改进MS SQL中的Sum和Rank性能

时间:2014-06-18 18:05:37

标签: sql sql-server database-performance

我有一个MS SQL表,它由Item Number和Date索引。我需要计算一系列日期(对于几个日期范围)中每个项目编号的销售总额,如下所示:

DECLARE @BeginDate DATE = '2014-06-11'
DECLARE @EndDate DATE = '2014-06-11'

INSERT INTO @Ranks
SELECT 
[ItemNumber],
Sum([Sales]),
row_number OVER (ORDER BY SUM([Sales]) DESC) AS [Rank]
WHERE [Date] BETWEEN @BeginDate AND @EndDate
GROUP BY ItemNumber

-- Some logic here (not a significant effect on performance)
DELETE FROM @Ranks

SET @BeginDate = '2014-05-11'
INSERT INTO @Ranks
SELECT 
[ItemNumber],
Sum([Sales]),
row_number OVER (ORDER BY SUM([Sales]) DESC) AS [Rank]
WHERE [Date] BETWEEN @BeginDate AND @EndDate
GROUP BY ItemNumber

-- Some logic here (not a significant effect on performance)
DELETE FROM @Ranks

-- Query runs several more times, at three, six, and twelve months

第一个问题:有没有办法可以重构这个,所以它只需要一个查询?第二,有没有更好的方法来计算排名?我的数据库足够大,需要几分钟才能运行。

1 个答案:

答案 0 :(得分:3)

我认为你想要条件聚合,所以你应该能够在一个查询中完成所有这些:

select t.*,
       row_number() over (order by sales_1 desc) as rank_1,
       row_number() over (order by sales_2 desc) as rank_2,
       row_number() over (order by sales_3 desc) as rank_3,
       row_number() over (order by sales_4 desc) as rank_4
from (SELECT ItemNumber,
             Sum(case when [date] between @BeginDate1 and @EndDate1 then Sales end) as Sales_1, 
             Sum(case when [date] between @BeginDate2 and @EndDate2 then Sales end) as Sales_2,
             Sum(case when [date] between @BeginDate3 and @EndDate3 then Sales end) as Sales_3,
             Sum(case when [date] between @BeginDate4 and @EndDate4 then Sales end) as Sales_4
      WHERE [Date] BETWEEN @BeginDate AND @EndDate
      GROUP BY ItemNumber
     ) t