1

(n)varchar(max)我对(n)varchar(<explicit-size>) T-SQL 代码(存储过程、函数)的“效率”(速度、内存使用)有疑问。我不是在询问它在列定义中的用法。

在现有代码中,我注意到很多类似的情况比如:

CREATE TABLE [table] (
    [column] nvarchar(1000)
)

DECLARE @var nvarchar(2000)
SELECT @var = [column] FROM  TABLE WHERE ...
SET @var = @var + @somethingelse + @anotherthing ...
SET @var = REPLACE(@var, N'search', N'lotstoreplacewith')
...

要点是(以上只是一个例子)我最终会从有限大小的字符串列中构建更长的字符串。很难/不方便知道和维护这些字符串可能会变得多大。

因此,如果我改为将这些 T-SQL 变量声明为nvarchar(max). 然后我不必担心它们可以达到的最大尺寸。它们类似于编程语言的“无限”字符串大小。

有人知道 SQL Server 如何“有效”地处理操作声明的变量的代码(n)varchar(max)吗?例如,它是否为这样的变量保留了大量空间(我希望它纯粹动态地处理它),或者CAST/CONVERT()使用它的字符串函数是否会受到一些性能损失?[如果相关,我必须支持 SQL Server 2008 R2 及更高版本。]

[编辑:有人建议我的问题与总是使用 nvarchar(MAX) 有什么缺点吗?. 但是,除一篇文章外,其他所有文章都varchar(max)列定义中引用,我的问题明确指出我正在询问T-SQL 代码(变量等)的性能。我在下面的问题上发布了一个答案(因为它很大),它借鉴了该帖子并用一些新信息对其进行了扩展。]

4

1 回答 1

1

总是使用 nvarchar(MAX) 有什么缺点吗?有一个答案https://stackoverflow.com/a/26120578/489865与 T-SQL 变量性能而不是列定义有关。

那篇文章的要点是运行SELECT @var='ABC'返回 1,000,000 行的查询,分配给定义为nvarchar(<size>)vs的变量nvarchar(max)

在 SQL Server 2008 R2 下,我同意发帖者的发现,nvarchar(max)它比nvarchar(<size>)示例中慢 4 倍。有趣的是,如果更改它以使分配做更多的工作,如下所示:

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(300)
DECLARE @SomeString NVARCHAR(300),
        @StartTime DATETIME
;
 SELECT @startTime = GETDATE()
;
 SELECT TOP 1000000
        @SomeString = 'ABC' + ac1.[name] + ac2.[name]
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2
;
 SELECT Duration    = DATEDIFF(ms,@StartTime,GETDATE())
;
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME
;
 SELECT @startTime = GETDATE()
;
 SELECT TOP 1000000
        @SomeString = 'ABC' + ac1.[name] + ac2.[name]
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2
;
 SELECT Duration    = DATEDIFF(ms,@StartTime,GETDATE())
;
GO
--===== Test Variable Assignment 1,000,000 times using VARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME
;
 SELECT @startTime = GETDATE()
;
 SELECT TOP 1000000
        @SomeString = 'ABC' + ac1.[name] + ac2.[name]
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2
;
 SELECT Duration    = DATEDIFF(ms,@StartTime,GETDATE())
;
GO

(注意+ ac1.[name] + ac2.[name])然后nvarchar(max)只需要两倍的时间。所以在实践中的表现nvarchar(max)可能比最初看起来要好。

于 2016-02-16T12:45:32.203 回答