繁体   English   中英

使用SQL Server 2008中的FOR XML PATH提高SQL查询的性能

[英]Improve performance of SQL query with a FOR XML PATH in SQL Server 2008

我试图使用For XML路径为用户连接LoadIds,这是整个查询的一部分,我验证了在计算此串联的LoadId列时已花费了最大时间。 以下是语法,有人可以建议一种有效地重写此方法的方法吗?

SELECT 
    Col1, col2, 
    LoadIds = STUFF((SELECT ' , ' + CAST([LoadId] AS varchar(5))
                     FROM Table1 AS t1
                     WHERE t1.[UserId] = [t2].[UserId]
                     FOR XML PATH ('')), 1, 2, '')
FROM 
    Table1 AS t2
GROUP BY 
    [UserId]

您可以做的一件事是在进行字符串聚合之前选择不同的用户ID:

SELECT t2.UserId, 
        STUFF((SELECT ' , ' + CAST([LoadId] AS varchar(8000))
               FROM Table1 t1
               WHERE t1.[UserId] = [t2].[UserId]
               FOR xml PATH ('')
              ), 1, 2, ''
             ) as LoadIds
FROM (SELECT DISTINCT userId
      FROM Table1 t2
     ) t2;

为了提高性能,对table1(UserId, LoadId)的索引也将有所帮助。

1)。 我会尝试在临时表或表变量中收集所需的数据,在其上创建一个索引,然后再进行隐式处理。

2)。 FOR XML PATH适用于小型记录集,对于大型记录集,我会尝试递归。

declare @T table (
    UserId     int        not null,
    RowNumber  int        not null,
    LoadId     varchar(5) not null

    primary key clustered (UserId, RowNumber)
);

insert into @T
select
    UserId,
    row_number() over(partition by UserId order by LoadId),
    CAST(LoadId AS varchar(5))    
from
    Table1 ;


with cte (UserId, RowNumber, LoadIds) as 
(
    select 
        UserId, 
        RowNumber,
        LoadIds = convert(varchar(8000), LoadId)
    from @T
    where RowNumber = 1

    union all

    select 
        t.UserId, 
        t.RowNumber,
        convert(varchar(8000), cte.LoadIds + ', ' + t.LoadId)
    from 
        cte inner join @T t on t.UserId = cte.UserId and t.RowNumber = cte.RowNumber + 1
)
select UserId, LoadIds = max(LoadIds) from cte group by UserId;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM