我希望提高我的家长/孩子 CTE 的表现。我想知道是否有一种新的、更好的、更快的方法。 CTE 只是遍历一个现在包含大约 40 万人的父子树。在 SSMS 中,该过程大约需要 5 到 8 秒。
每个人都通过经典的 CHILD ID(我的代码中的 UserID)与 PARENT ID(我的代码中的 SponsorID)相互关联。 UserID 是带有聚集索引的主键,称为 PK_UserID。 SponsorID 有一个名为 IX_SponsorID 的非聚集索引。
粘贴计划: https://www.brentozar.com/pastetheplan/?id=SyaDlDkC3
-- Engine To Build Parent/Child
;
WITH CTE
AS
(
-- The Anchor Person
SELECT UserID
,SponsorID
,0 AS Level
FROM CCMUsers
WHERE UserID = 45
UNION ALL
-- The Recursive People
SELECT e.UserID
,e.SponsorID
,CTE.Level + 1
FROM CCMUsers AS e
INNER JOIN CTE ON e.SponsorID = CTE.UserID
)
select * from CTE
添加索引
在 SponsorID 上添加索引以帮助加入性能:
CREATE INDEX idx_SponsorID ON CCMUsers (SponsorID)
使用查询提示
允许无限递归深度的选项(MAXRECURSION 0):
WITH CTE (QUERY OPTION (MAXRECURSION 0))
AS
-- other codes
增量CTE
一次仅递归一级以减少临时表大小:
;WITH Cte1 AS (SELECT * FROM CCMUsers WHERE UserID = 45),
Cte2 AS (SELECT * FROM Cte1 UNION ALL
SELECT c.* FROM Cte1 JOIN CCMUsers c ON c.SponsorID = Cte1.UserID),
Cte3 AS (SELECT * FROM Cte2 UNION ALL
SELECT c.* FROM Cte2 JOIN CCMUsers c ON c.SponsorID = Cte2.UserID)
SELECT * FROM Cte3
优化主播会员搜索
使用覆盖索引进行锚点查找以避免键查找:
CREATE INDEX ix_CCMUsers_covering ON CCMUsers (UserID, SponsorID) INCLUDE (Level)
分区 在 SponsorID 上对 CCMUsers 进行分区,以实现更高效的修剪