В поисках оптимизации запроса T- SQL, написанного для расчета скользящей суммы дохода 12M. Основная проблема заключается в том, что мне нужно рассчитать его по 6 измерениям, в результате чего получается более 45 000 комбинаций, каждая из которых требует собственного скользящего дохода. Каждая комбинация занимает около 5 минут для расчета. Из-за специфики бизнеса комбинации будут расти со временем.
Все действия необходимо выполнить как подзапрос.
DECLARE @NUMBER INT
DECLARE @ROWCOUNT INT = 0
DECLARE @REFERENCE VARCHAR(50)
SET @NUMBER =
(SELECT MAX(r.Row)
FROM (
SELECT
a.GroupKey
,a.LevelKey
,a.StateKey
,a.ProductKey
,a.OptionKey
,a.LocKey
,ROW_NUMBER() OVER(ORDER BY a.GroupKey ASC) AS Row
FROM Members AS a
GROUP BY
a.GroupKey
,a.LevelKey
,a.StateKey
,a.ProductKey
,a.OptionKey
,a.LocKey ) r)
BEGIN
DECLARE @OUTPUT TABLE (
RefKey VARCHAR(50)
,DateID INT
,GroupKey INT
,LevelKey INT
,StateKey INT
,ProductKey INT
,OptionKey INT
,LocKey INT
,Revenue DECIMAL(28,9)
,Rolling12Months DECIMAL(28,9)
)
WHILE @ROWCOUNT < @NUMBER
BEGIN
SET @REFERENCE =
(SELECT r.RefKey
FROM (
SELECT
r.Refkey
,r.Row
FROM (
SELECT
CONCAT( a.GroupKey, '-',a.LevelKey, '-',a.StateKey, '-',a.ProductKey, '-',a.OptionKey, '-',a.LocKey) AS RefKey
,ROW_NUMBER() OVER(ORDER BY a.GroupKey ASC) AS Row
FROM Members AS a
GROUP BY
a.GroupKey
,a.LevelKey
,a.StateKey
,a.ProductKey
,a.OptionKey
,a.LocKey ) r) r WHERE r.Row = @ROWCOUNT + 1 )
INSERT INTO @OUTPUT
SELECT
a.RefKey
,a.DateID
,a.GroupKey
,a.LevelKey
,a.StateKey
,a.ProductKey
,a.OptionKey
,a.LocKey
,a.Revenue
,Rolling12Months=a.Revenue + b.RM
FROM (
SELECT
CONVERT(datetime,STR(CI.DateID)) AS Date
,CI.DateID
,CI.GroupKey
,CI.LevelKey
,CI.StateKey
,CI.ProductKey
,CI.OptionKey
,CI.LocKey
,CONCAT( CI.GroupKey, '-',CI.LevelKey, '-',CI.StateKey, '-',CI.ProductKey, '-',CI.OptionKey, '-',CI.LocKey) AS RefKey
,SUM(CI.Revenue) AS Revenue
FROM Members AS CI
WHERE CONCAT( CI.GroupKey, '-',CI.LevelKey, '-',CI.StateKey, '-',CI.ProductKey, '-',CI.OptionKey, '-',CI.LocKey) = @REFERENCE
GROUP BY CI.DateID,CI.StateKey,CI.GroupKey ,CI.LevelKey,CI.StateKey,CI.ProductKey,CI.OptionKey ,CI.LocKey
) a
CROSS APPLY
(
SELECT RM=SUM(b.Revenue)
FROM
(
SELECT TOP 11 b.Date, b.Revenue
FROM (
SELECT
CONVERT(datetime,STR(CI.DateID)) AS Date
,CI.DateID
,CI.GroupKey
,CI.LevelKey
,CI.StateKey
,CI.ProductKey
,CI.OptionKey
,CI.LocKey
,CONCAT( CI.GroupKey, '-',CI.LevelKey, '-',CI.StateKey, '-',CI.ProductKey, '-',CI.OptionKey, '-',CI.LocKey) AS RefKey
,SUM(CI.Revenue) AS Revenue
FROM Members AS CI
WHERE CONCAT( CI.GroupKey, '-',CI.LevelKey, '-',CI.StateKey, '-',CI.ProductKey, '-',CI.OptionKey, '-',CI.LocKey) = @REFERENCE
GROUP BY CI.DateID,CI.StateKey,CI.GroupKey ,CI.LevelKey,CI.StateKey,CI.ProductKey,CI.OptionKey ,CI.LocKey
) b
WHERE b.Date < a.Date AND b.RefKey = a.RefKey
ORDER BY b.Date DESC
) b
) b
SET @ROWCOUNT = @ROWCOUNT + 1
END
SELECT * FROM @OUTPUT
END