SQL Server 2012:XML路径的替代方案

SQL Server 2012:XML路径的替代方案,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我的任务是重新处理一组现有的遗留查询。我发现的主要问题是,它们都使用XML PATH()在返回结果之前对各种临时表进行更新 它会像这样分解,我们创建一个临时表,将基本信息作为不同的值 OwnerId | FName | LName | Pets --------+-------+-------+------- PA1234 | Greg | Brady | ZB0013 | Peter | Brady | QX9999 | Bobby | Brady | 然后这个表需要从一个非常大的表

我的任务是重新处理一组现有的遗留查询。我发现的主要问题是,它们都使用
XML PATH()
在返回结果之前对各种临时表进行更新

它会像这样分解,我们创建一个临时表,将基本信息作为不同的值

OwnerId | FName | LName | Pets
--------+-------+-------+-------
PA1234  | Greg  | Brady |
ZB0013  | Peter | Brady |
QX9999  | Bobby | Brady |
然后这个表需要从一个非常大的表(几百万条记录)更新。这些表看起来像这样:

PetId | OwnerId | PetType
------+---------+-----------
100   | PA1234  | cat
101   | PA1234  | dog, bird
103   | PA1234  | gerbil
104   | ZB0013  | fish
105   | QX9999  | dog, cat
106   | QX9999  | dog, bird
107   | AA5555  | snake
OwnerId | FName | LName | Pets
--------+-------+-------+-------------------------
PA1234  | Greg  | Brady | cat; dog, bird; gerbil
ZB0013  | Peter | Brady | fish
QX9999  | Bobby | Brady | dog, cat; dog, bird
预期结果如下所示:

PetId | OwnerId | PetType
------+---------+-----------
100   | PA1234  | cat
101   | PA1234  | dog, bird
103   | PA1234  | gerbil
104   | ZB0013  | fish
105   | QX9999  | dog, cat
106   | QX9999  | dog, bird
107   | AA5555  | snake
OwnerId | FName | LName | Pets
--------+-------+-------+-------------------------
PA1234  | Greg  | Brady | cat; dog, bird; gerbil
ZB0013  | Peter | Brady | fish
QX9999  | Bobby | Brady | dog, cat; dog, bird
当前的查询会产生所需的结果,但需要永远。100条记录几乎需要5分钟才能返回结果,我觉得这太疯狂了

UPDATE #Temp 
SET Pets = STUFF((SELECT DISTINCT '; ' + P1.PetType
                  FROM Pet_Table P1 
                  WHERE P1.OwnerID = OuterT.OwnerId
                  FOR XML PATH('')), 1, 1, '')
FROM #Temp OuterT
我觉得,
COALESCE
会更快,但不知道如何在这种情况下工作,可能是CTE,我正在寻找任何建议


谢谢,如果需要更多信息或者我需要更好地解释,请告诉我。

5分钟100条记录太慢了。我怀疑你可能永远也得不到你真正想要的表演。但是,索引会有所帮助

首先,您需要正确地表达查询。您需要在
UPDATE
中指定
OuterT
——因为对
#Temp
的两个引用是不同的。您的版本本质上是在进行
交叉连接

UPDATE OuterT 
    SET Pets = STUFF((SELECT DISTINCT '; ' + P1.PetType
                      FROM Pet_Table P1 
                      WHERE P1.OwnerID = OuterT.OwnerId
                      FOR XML PATH('')
                     ), 1, 1, '')
    FROM #Temp OuterT;
然后,您需要索引。对于此查询:
Pet\u表(OwnerId,PetType)


另外,如果您可以去掉
选择DISTINCT
,那么这也会有帮助。

您是否通过查看计划来确定FOX XML路径确实是问题所在?其他表上是否有适当的索引


因为XML路径通常是高性能的,我从未见过它会导致您在这里确定的范围的递减。相反,我会查看计划,更深入地了解哪些索引正在使用(或未使用),并查看调整索引(添加包含列)或添加新索引是否可以解决您的问题。

通过查看计划,您是否确定FOX XML路径确实是问题所在?其他表上是否有适当的索引?@pmbAustin我肯定XML路径是问题所在。我在没有XML路径的情况下运行查询,大约需要5秒钟。使用XML PATH需要5分钟。使用以下说明分享您的执行计划:。我同意@pmbAustin的观点,因为我过去曾以惊人的性能广泛使用XML PATH。如果临时表很大,也许应该让脚本索引该临时表?如果没有任何索引,就会出现性能问题。或者,您可以使用一个永久表来保存此数据,并确保其索引正确。不幸的是,虽然我有权访问执行计划,但由于公司政策,我无法发布它。如果有什么特别的东西我应该找,那就太好了。我知道这一点帮助都没有——对不起