Оптимизация таблицы CTE - PullRequest
       6

Оптимизация таблицы CTE

0 голосов
/ 07 февраля 2020

У меня есть таблица, которая содержит 1,5 миллиона строк. У него есть действительный от и действительный до, и я создаю временной ряд из них. Я планирую объединить их с другими имеющимися у меня таблицами (переменные поведенческого типа, такие как ежемесячные платежи / счета и т. Д. c), но при создании таблицы с использованием приведенного ниже кода это займет вечность. Запуск на 1000 лучших занимает около 3 секунд. Топ 10000 около 50 секунд, поэтому я думаю, что время выполнения является экспоненциальным.

Ниже приведен код

SELECT
*
FROM
(
SELECT
    a.[PROP_NUM]
    ,b.table_code
    ,a.[RATE_UNIT_from]
    ,a.[RATE_UNIT_to]
    ,EOMONTH( a.[RATE_UNIT_from]) AS [Valid From]
    ,EOMONTH(CASE WHEN a.[RATE_UNIT_to] >= CAST(GETDATE() AS DATE) THEN CAST(GETDATE() AS DATE) ELSE a.[RATE_UNIT_to] END) AS [Valid To]
    ,ROW_NUMBER() OVER(PARTITION BY a.[PROP_NUM], EOMONTH(a.[RATE_UNIT_from]) ORDER BY a.[RATE_UNIT_to] DESC) AS [Row Number]
    INTO [dbo].[Historical LUC]
FROM [Grange_Prod].[dbo].[PROP_RATING_UNIT] as a
LEFT JOIN CODE_TABLE  as b
on a.prop_pru_tcode = b.table_code
WHERE a.[RATE_UNIT_TYPE_TCODE] = 'LUC' and b.table_type_code = 'LUC' and EOMONTH(CASE WHEN a.[RATE_UNIT_to] >= CAST(GETDATE() AS DATE) THEN CAST(GETDATE() AS DATE) ELSE a.[RATE_UNIT_to] END) >= '20131231'
) as z1
WHERE [Row Number] = 1
;
CREATE INDEX LUC ON [dbo].[Historical LUC] ([PROP_NUM], [Valid From], [Valid To])
;
DROP TABLE IF EXISTS [LUC Time Series]
;
WITH CTE AS
(
SELECT
    z1.[PROP_NUM]
    ,z1.[table_code]
    ,z1.[RATE_UNIT_from]
    ,z1.[RATE_UNIT_to]
    ,CASE WHEN z1.[Valid From] <= '20140101' THEN '20140101' ELSE z1.[Valid From] END AS [Valid From]
    ,z1.[Valid To]
FROM [dbo].[Historical LUC] AS z1
UNION ALL
SELECT
    [PROP_NUM]
    ,[table_code]
    ,[RATE_UNIT_from]
    ,[RATE_UNIT_to]
    ,EOMONTH(DATEADD(MONTH, 1, [Valid From])) AS [EOM Date]
    ,[Valid To]
    FROM CTE
WHERE [Valid From] < [Valid To]
)
SELECT
    [PROP_NUM]
    ,[table_code]
    ,EOMONTH(DATEADD(MONTH, 1, [Valid From])) AS [EOM Date]
    INTO [LUC Time Series]
FROM CTE AS a
ORDER BY [PROP_NUM], [Valid From]
OPTION (MAXRECURSION 32767)

Можно ли как-нибудь улучшить этот запрос? Я открыт для любых предложений.

1 Ответ

1 голос
/ 07 февраля 2020

Я удивлен SQL Север борется с этим запросом. В конце концов, рекурсивный запрос не содержит объединения, поэтому для каждой строки вы всегда генерируете только одну новую строку (следующий месяц до конца периода).

Альтернативой может быть создание таблицы месяцев с 2014. Это меньше, чем 100 строк. Тогда вы можете написать что-то вроде этого, что не должно занять много времени для обработки:

select *
from [dbo].[Historical LUC] h
join months m on m.month between h.[Valid From] and h.[Valid To];
...