Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql CTE表优化_Sql_Sql Server_Tsql_Common Table Expression - Fatal编程技术网

Sql CTE表优化

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

我有一个包含150万行的表。它有一个有效的from和一个有效的to,我正在创建这些的时间序列。我计划将这些表合并到其他表中,我有行为类型变量,如每月付款/账单等,但使用下面的代码创建表时,需要花费很长时间。在前1000名跑步大约需要3秒钟。Top 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)

我有没有办法进一步强化这个问题?我愿意接受任何建议。

我很惊讶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表格那样需要几个小时。