T-SQL代码中varchar(max)的效率
Efficiency of varchar(max) in T-SQL code
我有一个关于 (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')
...
要点是(以上只是一个例子)我最终是从有限大小的字符串列中构建更长的字符串。 difficult/inconvenient 知道并维护这些字符串可以变得多大。
所以,如果我改为将这些 T-SQL 变量声明为 nvarchar(max)
,对我来说会更简单。这样我就不必担心它们可以达到的最大尺寸。它们类似于编程语言的 "unlimited" 字符串大小。
有人知道 "efficiently" SQL 服务器如何处理操纵声明 (n)varchar(max)
变量的代码吗?例如,它是否为这样的变量保留了大量的 space(我 希望 它纯粹动态地处理它),或者 CAST/CONVERT()
,或者使用它的字符串函数会受到一些性能损失吗? [如果相关,我必须支持 SQL Server 2008 R2 以上版本。]
[编辑:有人认为我的问题与 Are there any disadvantages to always using nvarchar(MAX)? 重复。但是,除了一个 post 之外,其他所有 列定义 中都提到了 varchar(max)
,我的问题明确指出我问的是 T-SQL代码(变量等)性能。我正在 post 回答我下面的问题(因为它很大),它借鉴了 post 并用一些新信息对其进行了扩展。]
在 Are there any disadvantages to always using nvarchar(MAX)? there is one answer 中,它与 T-SQL 变量性能相关,而不是列定义。
post 的要点是 运行 SELECT @var='ABC'
查询返回 1,000,000 行,分配给定义为 nvarchar(<size>)
与 nvarchar(max)
的变量。
在 SQL Server 2008 R2 下,我同意 poster 的发现,即示例中 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)
的性能命中率可能比乍看起来要好。
我有一个关于 (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')
...
要点是(以上只是一个例子)我最终是从有限大小的字符串列中构建更长的字符串。 difficult/inconvenient 知道并维护这些字符串可以变得多大。
所以,如果我改为将这些 T-SQL 变量声明为 nvarchar(max)
,对我来说会更简单。这样我就不必担心它们可以达到的最大尺寸。它们类似于编程语言的 "unlimited" 字符串大小。
有人知道 "efficiently" SQL 服务器如何处理操纵声明 (n)varchar(max)
变量的代码吗?例如,它是否为这样的变量保留了大量的 space(我 希望 它纯粹动态地处理它),或者 CAST/CONVERT()
,或者使用它的字符串函数会受到一些性能损失吗? [如果相关,我必须支持 SQL Server 2008 R2 以上版本。]
[编辑:有人认为我的问题与 Are there any disadvantages to always using nvarchar(MAX)? 重复。但是,除了一个 post 之外,其他所有 列定义 中都提到了 varchar(max)
,我的问题明确指出我问的是 T-SQL代码(变量等)性能。我正在 post 回答我下面的问题(因为它很大),它借鉴了 post 并用一些新信息对其进行了扩展。]
在 Are there any disadvantages to always using nvarchar(MAX)? there is one answer 中,它与 T-SQL 变量性能相关,而不是列定义。
post 的要点是 运行 SELECT @var='ABC'
查询返回 1,000,000 行,分配给定义为 nvarchar(<size>)
与 nvarchar(max)
的变量。
在 SQL Server 2008 R2 下,我同意 poster 的发现,即示例中 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)
的性能命中率可能比乍看起来要好。