我想知道SQL Server中的计算列是否有任何性能提升,请查看下面的示例。
现在我在生产环境中有一个更新表的存储过程,将两个VARCHAR
列连接到另一列,创建时为NULL
。
如果我想将更新逻辑切换为使用计算列,这将在加载数据时自动生成值。
问题是:这会帮助我增加派生列的处理时间吗?此时我无法真正在生产环境中进行更改和测试,但在此之前,通常,使用计算列与更新的任何优势。
请注意,更新后的列将保持不变,有效记录总数将达到百万。
更新
表格定义
CREATE TableA
(
ColumnA VARCHAR(50),
ColumnB VARCHAR(50),
ColumnC VARCHAR(50)
)
ColumnA
和ColumnB
将填充SSIS包中的数据,ColumnC
将由存储过程更新,
UPDATE TableA
SET ColumnC = ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
这些更新将影响最多数百万条记录。
如果我想使用:
CREATE TableA
(
ColumnA VARCHAR(50),
ColumnB VARCHAR(50),
ColumnC as ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
)
这会更快填充ColumnC
吗?
答案 0 :(得分:1)
在更新中,我建议您在哪里不要更新不需要更新的行。更新将锁定并在事务日志中放入一个条目。
UPDATE TableA
SET ColumnC = ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
WHERE ColumnC <> ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
您可以通过以下方式控制增长事务日志:
(这是来自内存所以可能有语法错误)
select 1
while (@@rowcount > 0)
begin
UPDATE top(10000) TableA
SET ColumnC = ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
WHERE ColumnC <> ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
end
Computed列是一个虚拟列,除非它是持久的。因此,如果您不坚持,则没有额外的时间来加载ColumnA和ColumnB。 ColumnC上的选择将在运行时计算得更慢。
如果ColumnC被持久化将与更新类似,但在插入或更新ColumnA或ColumnB时即时完成。
如评论中所述,计算列是一致的。更新仅在上次运行命令时保持一致。