Sql-Server

在 cast/convert 中使用 varchar(max) 而不是 varchar(n) 是否有任何性能影響?

  • August 1, 2021

考慮以下表達式,它從日期時間值截斷(不捨入)毫秒:

declare @now datetime2 = sysdatetime();
select @now;
select convert(datetime2, convert(varchar(20), @now, 120));

-- Output
2021-07-30 09:38:33.5566666
2021-07-30 09:38:33.0000000

注意varchar(20). 我不喜歡那個特定的長度值,因為如果我應該更改我的數據類型,可能會失去數據:

declare @now datetimeoffset = sysdatetimeoffset() at time zone 'Pacific Standard Time';
select @now;
select convert(datetimeoffset, convert(varchar(20), @now, 120));

-- Output
2021-07-30 02:39:12.7200000 -07:00
2021-07-30 02:39:12.0000000 +00:00 -- oops, we lost the time zone too!

因此,我寧願使用以下內容:

declare @now datetimeoffset = sysdatetimeoffset() at time zone 'Pacific Standard Time';
select @now;
select convert(datetimeoffset, convert(varchar(max), @now, 120)); -- note MAX not N

-- Output
2021-07-30 02:41:16.4566666 -07:00
2021-07-30 02:41:16.0000000 -07:00

varchar(max)我的問題是,使用over是否有任何有意義的性能影響varchar(N)——包括但不限於記憶體分配?

我知道如果在 predicates 中使用數據類型而不是數據類型會對查詢性能產生影響(max)``(N),但在我的特定範例中我沒有這樣做 - 只是分配varchars 然後在將它們轉換回所需的數據類型後將它們丟棄。

首先,回答你的問題:

是的,它會影響性能,因為需要分配空間來保存查詢引擎中的大值。

在您的情況下,您還可以使用適當大的尺寸,例如varchar(50)可以輕鬆容納您需要的任何東西。

但你不應該首先做這些。

在舍入日期時,您不應轉換為varchar和返回,因為這具有較差的性能,以及涉及文化/風格的問題。

相反,使用標準的捨入技術:

declare @now datetimeoffset = sysdatetimeoffset() at time zone 'Pacific Standard Time';
declare @epoch datetimeoffset = CAST(@now AS date);
select dateadd(
   second,
   datediff(second, @epoch, @now at time zone 'utc'),
   @epoch) at time zone 'Pacific Standard Time';

引用自:https://dba.stackexchange.com/questions/297390