示例表格结构:
EmployeeId TeamleaderId TopTeamleaderId LEVEL ParentTree CompanyId
1 0 0 0 NULL 1
2 1 1 1 2>1 1
3 2 1 2 3>2>1 1
TeamleaderId
foreignKey
引用同一个表中的EmployeeId
目标:
只要在包含EmployeeId
的表格中插入行,TeamleaderId
,CompanyId
会自动将TopTeamleaderId
,LEVEL
和ParentTree
填入AFTER INSERT
触发器
代码:
WITH CTE AS (
SELECT EmployeeId, TeamleaderId,0 AS [Level], CAST(EmployeeId AS varchar(100)) AS Heirarchy, TopTeamleaderId
FROM dbo.Employee
WHERE EmployeeId IN (SELECT EmployeeId FROM Employee WHERE TeamleaderId IS NULL
AND CompanyId IN(SELECT DISTINCT CompanyId FROM INSERTED))
UNION ALL
SELECT mgr.EmployeeId, mgr.TeamleaderId, CTE.[Level] +1 AS [Level],
CAST(( CAST(mgr.EmployeeId AS VARCHAR(100)) + '>' + CTE.Heirarchy) AS varchar(100)) AS Heirarchy, CTE.TopTeamleaderId
FROM CTE
INNER JOIN dbo.Employee AS mgr
ON TaskCTE.EmployeeId = mgr.ParentTeamleaderId
)
UPDATE Employee SET [LEVEL] = TC.[LEVEL], ParentTree = TC.Heirarchy, TopTeamleaderId = TC.TopTeamleaderId
FROM dbo.Employee AS Employee
JOIN (SELECT * FROM CTE WHERE EmployeeId IN(SELECT DISTINCT EmployeeId FROM INSERTED) AND ParentTeamleaderId IS NOT NULL) TC
ON
Employee.EmployeeId = TC.EmployeeId
问题: 想象一下,公司中有100万名员工,这个查询需要很长时间才能执行。如何优化它,以便只插入插入行的父项?
答案 0 :(得分:2)
递归CTE非常棒,但正如您所看到的那样,性能可能会受到更大层次结构的影响。我坚信临时表格中没有羞耻。
以下将在0.784秒内生成200K点层次结构。
示例强>
Select EmployeeId
,TeamleaderId
,Lvl=1
,TopTeamleaderId = 0
,ParentTree=cast(EmployeeId as varchar(500))
,CompanyID
Into #TempBld
From Employee
Where TeamleaderId is null
Declare @Cnt int=1
While @Cnt<=30 --<< Set Your Max Level
Begin
Insert Into #TempBld
Select A.EmployeeId
,A.TeamleaderId
,B.Lvl+1
,IIF(B.Lvl=1,B.EmployeeId,B.TopTeamleaderId)
,concat(A.EmployeeId,'>',B.ParentTree)
,A.CompanyID
From Employee A
Join #TempBld B on (B.Lvl=@Cnt and A.TeamleaderId=B.EmployeeId)
Set @Cnt=@Cnt+1
End
--Select * from #TempBld Order by ParentTree
<强>返回强>