我一直认为CONCAT函数实际上是+(字符串连接)的包装,并带有一些额外的检查,以使我们的生活更轻松。
我还没有找到任何关于这些功能是如何实现的内部细节。至于性能,当数据在循环中连接时,调用似乎会产生开销CONCAT
(这似乎很正常,因为有额外的 NULL 句柄)。
几天前,一位开发人员修改了一些字符串连接代码(从+
到 ,CONCAT)
因为不喜欢语法并告诉我它变得更快。
为了检查情况,我使用了以下代码:
DECLARE @V1 NVARCHAR(MAX)
,@V2 NVARCHAR(MAX)
,@V3 NVARCHAR(MAX);
DECLARE @R NVARCHAR(MAX);
SELECT @V1 = REPLICATE(CAST('V1' AS NVARCHAR(MAX)), 50000000)
,@V2 = REPLICATE(CAST('V2' AS NVARCHAR(MAX)), 50000000)
,@V3 = REPLICATE(CAST('V3' AS NVARCHAR(MAX)), 50000000);
这是变体一:
SELECT @R = CAST('' AS NVARCHAR(MAX)) + '{some small text}' + ISNULL(@V1, '{}') + ISNULL(@V2, '{}') + ISNULL(@V3, '{}');
SELECT LEN(@R); -- 1200000017
这是变体二:
SELECT @R = CONCAT('{some small text}',ISNULL(@V1, '{}'), ISNULL(@V2, '{}'), ISNULL(@V3, '{}'))
SELECT LEN(@R); -- 1200000017
对于较小的字符串,没有差异。在某些时候,CONCAT
变体会变得更快:
我想知道有人可以分享一些内部结构或解释其行为,因为似乎可能存在一条规则,最好使用CONCAT
.
版本:
Microsoft SQL Server 2022 (RTM-CU8) (KB5029666) - 16.0.4075.1 (X64) 2023 年 8 月 23 日 14:04:50 版权所有 (C) 2022 Windows Server 2019 Standard 10.0(内部版本 17763)上的 Microsoft Corporation 标准版(64 位) :)(管理程序)
确切的脚本如下所示:
DECLARE @V1 NVARCHAR(MAX)
,@V2 NVARCHAR(MAX)
,@V3 NVARCHAR(MAX);
DECLARE @R NVARCHAR(MAX);
SELECT @V1 = REPLICATE(CAST('V1' AS NVARCHAR(MAX)), 50000000)
,@V2 = REPLICATE(CAST('V2' AS NVARCHAR(MAX)), 50000000)
,@V3 = REPLICATE(CAST('V3' AS NVARCHAR(MAX)), 50000000);
--SELECT @R = CAST('' AS NVARCHAR(MAX)) + '{some small text}' + ISNULL(@V1, '{}') + ISNULL(@V2, '{}') + ISNULL(@V3, '{}'); -- 00:00:45 -- 00:01:22 -- 00:01:20
--SELECT LEN(@R); -- 300000017
SELECT @R = CONCAT('{some small text}',ISNULL(@V1, '{}'), ISNULL(@V2, '{}'), ISNULL(@V3, '{}')) -- 00:00:11 -- 00:00:16 -- 00:00:10
SELECT LEN(@R); -- 300000017
我正在更改 REPLICATE 函数的最后一个参数,以便为连接生成更大的字符串。然后,我将每个变体执行三次。