Sql CTE表优化
我有一个包含150万行的表。它有一个有效的from和一个有效的to,我正在创建这些的时间序列。我计划将这些表合并到其他表中,我有行为类型变量,如每月付款/账单等,但使用下面的代码创建表时,需要花费很长时间。在前1000名跑步大约需要3秒钟。Top 10000大约50秒,因此我认为运行时间是指数级的 下面是代码Sql CTE表优化,sql,sql-server,tsql,common-table-expression,Sql,Sql Server,Tsql,Common Table Expression,我有一个包含150万行的表。它有一个有效的from和一个有效的to,我正在创建这些的时间序列。我计划将这些表合并到其他表中,我有行为类型变量,如每月付款/账单等,但使用下面的代码创建表时,需要花费很长时间。在前1000名跑步大约需要3秒钟。Top 10000大约50秒,因此我认为运行时间是指数级的 下面是代码 SELECT * FROM ( SELECT a.[PROP_NUM] ,b.table_code ,a.[RATE_UNIT_from] ,a.[RATE
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)
我有没有办法进一步强化这个问题?我愿意接受任何建议。我很惊讶SQL Server无法处理此查询。毕竟,递归查询不包含联接,因此对于每一行,您总是在下个月只生成一个新行,直到周期结束 另一种方法是创建2014年以来的月份表。那不到100行。然后你可以写这样的东西,不需要花太多时间来处理:
select *
from [dbo].[Historical LUC] h
join months m on m.month between h.[Valid From] and h.[Valid To];
输出应该是什么样的?你能把问题缩小到一个包含你需要的列和预期输出的表中吗?这个表将有3列。物业编号、类型和每个月的开放日期,从今天开始。很抱歉,我的手机无法添加物理表最终的表包含525m行。我认为这就是它的困难所在。是的,好吧,递归过程当然不知道它将生成多少数据,所以内存访问可能不是很好。这与我的查询不同,在我的查询中,DBMS只需要处理一个至少可以猜测的连接。DBMS是为了快速连接而编写的,所以很有可能:-我如何填充前一个非空行中缺少的行?我不理解这个问题。在我看来,在其范围内,每个现有行和月份生成一个结果行。这也正是join所做的。哦,我明白你的意思。不要在日期键上合并,也不要只在属性键上合并,并且有一些基于日期等分配类型的逻辑。干杯,伙计。希望这不会像CTE表格那样需要几个小时。