我试图使用FOR XML PATH技术连接结果集中的字符串,但遇到了一些性能问题。我想知道是否有任何方法可以改进这种类型的查询。
我正在编写一个报告查询,用于检查Part
表的所有15000行的库存余额。这些部件可用于存储在Equipment
表中的一件或多件设备,该表还有大约12000行。客户希望报告具有逗号分隔的设备,其中每个部件都使用这些设备。
我首先创建了一个返回零件和设备的完整连接的查询
SELECT PartName, Balance, EquipmentName as UsedOn
FROM Part p
LEFT OUTER JOIN EquipmentPart ep ON p.PartID = ep.PartID
LEFT INNER JOIN Equipment e ON ep.EquipmentID = e.EquipmentID
这将在1秒内返回49000行的结果集(根据SQL Server Management Studio),但未完成最终目标。
然后我尝试通过执行以下操作来专注于获取逗号分隔字段
SELECT PartName, Balance,
STUFF((SELECT ',' + EquipmentName
FROM Equipment e JOIN EquipmentPart ep ON e.EquipmentID = ep.EquipmentID
WHERE ep.PartID = p.PartID
FOR XML PATH('')) as UsedOn
FROM Part p
这花了8分多钟才终于杀了它;它只通过了15000行中的8000个。
我当前的解决方案将第一个查询与FOR XML PATH子查询相结合
WITH PartBalances AS
(SELECT PartID, PartName, Balance, EquipmentName as UsedOn
FROM Part p
LEFT OUTER JOIN EquipmentPart ep ON p.PartID = ep.PartID
LEFT INNER JOIN Equipment e ON ep.EquipmentID = e.EquipmentID
)
SELECT PartName, Balance,
STUFF ((SELECT ',' + UsedOn
FROM PartBalances p2
WHERE p1.PartID = p2.PartID
FOR XML PATH(''))
FROM PartBalances p1
GROUP BY PartID, PartName, Balance
这似乎回归了我想要的,但它需要一分钟。一分钟是可以接受的,但我希望能有更好的东西。
有什么我做错了或愚蠢的吗?有没有办法避免制作15000个子查询?
你能尝试运行这个版本的查询吗?
SELECT PartName, Balance,
STUFF((SELECT ',' + EquipmentName
FROM EquipmentPart ep JOIN
Equipment e
ON e.EquipmentID = ep.EquipmentID
WHERE ep.PartID = p.PartID
FOR XML PATH('')
), 1, 1, '') as UsedOn
FROM Part p;
LEFT JOIN
可能会使优化器混乱。
WITH PartBalances AS
(SELECT PartID, PartName, Balance, EquipmentName as UsedOn
FROM Part p
JOIN EquipmentPart ep ON p.PartID = ep.PartID
JOIN Equipment e ON ep.EquipmentID = e.EquipmentID
)
SELECT PartName, Balance,
STUFF ((SELECT ',' + UsedOn
FROM PartBalances p2
WHERE p1.PartID = p2.PartID
FOR XML PATH(''))
FROM PartBalances p1
GROUP BY PartID, PartName, Balance