我对T-SQL代码中的(n)varchar(max)
与(n)varchar(<explicit-size>)
的“效率”(速度,内存使用情况)(存储过程,函数)有疑问。我不询问它在列定义中的用法。
在现有代码中,我注意到很多场景沿着,说:
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。]
[编辑:有人建议我的问题与Are there any disadvantages to always using nvarchar(MAX)?重复。但是,除了一个帖子之外,其他所有帖子都引用了列定义中的varchar(max)
,我的问题明确指出我要求 T-SQL代码(变量等)。 )表现。我在下面的问题中发布了一个答案(因为它很大),该问题借鉴了该帖子并使用一些新信息进行了扩展。]
答案 0 :(得分:0)
在Are there any disadvantages to always using nvarchar(MAX)?中,有一个答案https://stackoverflow.com/a/26120578/489865与T-SQL变量的性能有关,而与列定义无关。
该帖子的要点是运行SELECT @var='ABC'
个查询,返回1,000,000行,分配定义为nvarchar(<size>)
与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)
的性能可能比最初看起来更好。