使用当前值更新列

时间:2010-12-15 21:36:41

标签: sql-server optimization

我有一个存储过程,它应该有条件地更新同一个表中的一堆字段。有条件地,因为对于每个字段,我也传递一个“脏”标志,只有当flag设置为1时才应更新字段。

所以我要做以下事情:

create proc update 
@field1 nvarchar(1000), @field1Dirty bit, ...other fields...
as 
begin
    update mytable
    set field1 = case when @field1dirty = 1 then @field1 else field1 end,
    ... same for other fields
end 
go

问题 - SQL Server(2008)是否足够智能,如果已经为其分配了自己的值,则不会对字段进行物理更新,例如@ field1dirty = 0?

4 个答案:

答案 0 :(得分:5)

Question - is SQL Server (2008) smart enough to not physically update
     

如果已经分配了自己的字段   值,如果@ field1dirty =的情况   0?

不,你应该添加一个说明...... where field <> the value you are updating to的where子句。

这一开始看起来并不是什么大不了的事,但事实上它可能会产生大量的开销。举个例子,考虑一下触发器。如果更新表中的每个字段,则会触发该行的每一行。 YIKES,这是很多代码执行,这是不必要的,特别是如果说代码,将更新行移动到日志表。我相信你明白了。

请记住,您正在更新该字段,它恰好与之前的值相同。发生这种情况实际上很好,因为这意味着您仍然可以将字段计数为已修改(想想时间戳等)。如果它不认为将字段更新为相同的值正在修改该行,您将无法知道是否有人无意中(或故意)尝试更改数据。

由于评论而更新: 链接到coalesce function

实施例: 用于处理存储过程中的空参数值

Update Table SET My_Field = COALESCE(@Variable, My_Field)

在将字段更新为相同值之前,这并没有解决我所说的内容,但它确实允许您检查参数并有条件地更新字段。

答案 1 :(得分:2)

SQL在写入之前不检查该值。无论如何它都会覆盖它。

答案 2 :(得分:2)

SQL Server将执行更新。该行将更新为整行,因此如果该行中的一列确实具有FieldxDirty = 1,则无论如何都需要更新。 SET子句中没有获得优化。

@ Kevin的答案不仅仅是优化SET子句。

答案 3 :(得分:0)

很抱歉来到这里有一个意见,但我无处可写:-) 至少应该有一种“提示”可能告诉UPDATE语句通常不会更新到相同的值。

我至少有两个理由可以考虑: 1st:要更新的值可能是一个复杂的表达式,在WHERE子句中再次表达它是浪费执行时间(更不用说维护表达式更改)了。也想想NULL值! 防爆。 UPDATE X SET A = B WHERE ISNULL(A,'')&lt;&gt; ISNULL(B, '')

第二:我们有一个同步镜像场景,其中“备份”服务器实际放置在城市的另一部分。这意味着,当备份服务器执行写操作时,首先会写入磁盘写入。写入和跳过写入之间存在巨大的时间差异。当开发人员创建应用程序时,他们在没有镜像的测试环境中工作。大多数UPDATE语句都没有更改值,但在测试环境中无关紧要。在使用镜像将应用程序部署到生产之后,我们真的很想拥有“仅改变价值”的提示。与编写

相比,读取原始值并检查它并不需要时间