【发布时间】:2015-03-18 04:02:57
【问题描述】:
我最近问了一个关于 CTE 和使用没有真正根记录的数据的问题(即,根记录不是具有 NULL parent_Id,而是它自己的父级)
问题链接在这里; Creating a recursive CTE with no rootrecord
已提供该问题的答案,我现在拥有所需的数据,但我对我认为可用的两种方法之间的区别感兴趣。
产生我需要的数据的方法是创建一个带有清理过的父数据的临时表,然后对其运行递归 CTE。如下所示;
Select CASE
WHEN Parent_Id = Party_Id THEN NULL
ELSE Parent_Id
END AS Act_Parent_Id
, Party_Id
, PARTY_CODE
, PARTY_NAME
INTO #Parties
FROM DIMENSION_PARTIES
WHERE CURRENT_RECORD = 1),
WITH linkedParties
AS
(
Select Act_Parent_Id, Party_Id, PARTY_CODE, PARTY_NAME, 0 AS LEVEL
FROM #Parties
WHERE Act_Parent_Id IS NULL
UNION ALL
Select p.Act_Parent_Id, p.Party_Id, p.PARTY_CODE, p.PARTY_NAME, Level + 1
FROM #Parties p
inner join
linkedParties t on p.Act_Parent_Id = t.Party_Id
)
Select *
FROM linkedParties
Order By Level
我还尝试通过定义两个 CTE 来检索相同的数据。一个模拟上面的临时表的创建,另一个执行相同的递归工作,但引用初始 CTE 而不是临时表;
WITH Parties
AS
(Select CASE
WHEN Parent_Id = Party_Id THEN NULL
ELSE Parent_Id
END AS Act_Parent_Id
, Party_Id
, PARTY_CODE
, PARTY_NAME
FROM DIMENSION_PARTIES
WHERE CURRENT_RECORD = 1),
linkedParties
AS
(
Select Act_Parent_Id, Party_Id, PARTY_CODE, PARTY_NAME, 0 AS LEVEL
FROM Parties
WHERE Act_Parent_Id IS NULL
UNION ALL
Select p.Act_Parent_Id, p.Party_Id, p.PARTY_CODE, p.PARTY_NAME, Level + 1
FROM Parties p
inner join
linkedParties t on p.Act_Parent_Id = t.Party_Id
)
Select *
FROM linkedParties
Order By Level
现在这两个脚本在同一台服务器上运行,但是临时表方法在大约 15 秒内产生结果。
多重 CTE 方法需要 5 分钟以上(事实上,我从来没有等到结果返回)。
临时表方法会更快吗?
我认为它的价值与记录数有关。基表中有 20 万条记录,在处理大型数据集时,内存 CTE 性能严重下降,但我似乎无法证明这一点,所以我想咨询专家。
非常感谢
【问题讨论】:
-
CTE 只是语法 - 它被评估。 #temp 已实现。这是有据可查的。
标签: tsql common-table-expression