我正在改进使用FOR XML PATH('')函数使用20列的视图性能。该视图还调用其他字段使用非聚集视图CTE,子查询和CAST函数,但我现在不关心它们。FOR XML PATH性能改进挑战
该视图是一个非聚集视图,每5分钟由作业选择该视图以将新数据显示给客户端应用程序。因此底层源表格正在更新并每隔5分钟插入一个井。
我已经在适当的地方创建了群集和非群集索引。在创建相应索引之前对源表上的各个视图组件进行了测试,之后选择了最佳路由。所以,我在索引方面做得很好。在所有指标上,填充因子值几乎为100。
我的假设是,查询速度放缓了很多,因为我使用的针对20列XML PATH(“”)......
CREATE VIEW MyView
AS
col1,
Col2,
(SELECT CAST(Mytbl.[EmpId] AS NVARCHAR(50)) + '|' FROM MyDB.dbo.Mytbl_Optimized AS t1 (NOLOCK)
LEFT OUTER JOIN AnotherDB.dbo.Another-tbl AS t2 WITH (NOLOCK)
ON t1.EmpId = t2.EmpId
WHERE AnotherDB.dbo.Table3.MyId = t1.MyId
FOR XML PATH('')) AS MyConcatenatedID
FROM AnotherDB.dbo.Table3
我试图用它确定一个CASE语句如果每个列都带有FOR XML PATH('')任何要逐行连接的基础,然后仅当is有2个或更多个值连接到一个字符串时才使用FOR XML PATH('')。但正如我所期望的性能是可怕的......
,CASE
WHEN
(SELECT
LEN(EmpId) - LEN(REPLACE(EmpId, '|', '')) AS [CountOfConcatinated_EmpId]
FROM ISSearch..SearchBid WITH (NOLOCK)
) > 1 -- this determis if values are concatenated or not.
THEN
(SELECT CAST(Mytbl.[EmpId] AS NVARCHAR(50)) + '|' FROM MyDB.dbo.Mytbl_Optimized AS t1 (NOLOCK)
LEFT OUTER JOIN AnotherDB.dbo.Another-tbl AS t2 WITH (NOLOCK)
ON t1.EmpId = t2.EmpId
WHERE AnotherDB.dbo.Table3.MyId = t1.MyId
FOR XML PATH(''))
ELSE
(SELECT CAST(Mytbl.[EmpId] AS NVARCHAR(50)) + '|' FROM MyDB.dbo.Mytbl_Optimized AS t1 (NOLOCK)
LEFT OUTER JOIN AnotherDB.dbo.Another-tbl AS t2 WITH (NOLOCK)
ON t1.EmpId = t2.EmpId
WHERE AnotherDB.dbo.Table3.MyId = t1.MyId)
END AS EmpId
FROM AnotherDB.dbo.MyView;
现在我考虑已经由FOR XML PATH(“”)的所有20列,在视图单独的列的函数字符串连接在一起的缓存选项,但需要不断更新(每5分钟)。
任何想法或替代解决方案?
我假设'AnotherDB.dbo.Another-tbl作为t2'是一个虚拟名称,但那些需要离开连接(或在那里)?至少在提供的查询中,他们似乎没有做任何事情。我想知道一些其他的事情:1)有多少行被连接到'MyConcatednatedId'的每个值中2)在'Table3'中有多少行3)它现在的表现有多慢4)你有多快需要它? – Xedni
使用[粘贴计划@ brentozar.com](https://www.brentozar.com/pastetheplan/)分享您的执行计划以下是说明:[如何使用粘贴计划](https://www.brentozar的.com/pastetheplan /指令/)。 – SqlZim