Skip to main content
黑话筒

一个因拼接字符串引起的SQL Server性能问题

在做一个薪资计算Log功能时,我为了得到当前步骤中参与计算的人和薪资项数据,采用了类似以下的写法:

DECLARE @combine NVARCHAR(MAX)
SET @combine = ''

SELECT
    @combine = @combine + ',' + empcode
FROM
    emphr

PRINT @combine

当我在28的ESL数据库上(emphr表中的数据共有28000条)执行这个脚本时,运行时间超过10秒(我没耐心等下去,因为我知道这属于性能问题) 当我把参与拼接的员工数量减小到1000,速度很快。随着人数的增加,消耗时间成指数(大概)增长。当人数是5000人时,消耗6秒,6000人时,消耗14秒。 在网上找到了一个佐证:

Be careful with string concatenations in sql server with big strings

于是从网上找找如何高效的实现这种拼接。 最终的解决办法参考Concatenate column values as single value sql server 2005

DECLARE @combine NVARCHAR(MAX)

SELECT
    @combine = (
        SELECT ',' + empcode
        FROM
            emphr
        FOR XML PATH(''))
PRINT @combine

输出为:,A000092112,A000100247,A000100353,A000100 效率为:

Third Test

这是利用SQL Server自带的功能,将表数据转换成XML。但我们指定了PATH("),就意味着生成的XML节点是单纯的文字节点,没有标签包裹。 如果把写成PATH( 'name ')

DECLARE @combine NVARCHAR(MAX)

SELECT
    @combine = (
        SELECT ',' + empcode
        FROM
            emphr
        FOR XML PATH('name'))
PRINT @combine

输出为:

,A000092112,A000100247,A000100353,A000100366

参考资料: