gpt4 book ai didi

sql - 如果不同/更改则更新

转载 作者:行者123 更新时间:2023-12-01 19:09:33 24 4
gpt4 key购买 nike

是否可以在sql中执行更新语句,但仅在更新不同时才更新?

例如

如果在数据库中,col1 = "hello"

update table1 set col1 = 'hello'

不应执行任何类型的更新

但是,如果

update table1 set col1 = "bye"

应该执行更新。

最佳答案

在查询编译和执行期间,SQL Server 不会花时间来确定 UPDATE 语句是否会实际更改任何值。它只是按预期执行写入,即使是不必要的。

在这样的场景

update table1 set col1 = 'hello'

您可能认为 SQL 不会执行任何操作,但它会执行所有必要的写入操作,就像您实际更改了值一样。对于物理表(或聚集索引)以及该列上定义的任何非聚集索引都会发生这种情况。这会导致写入物理表/索引、重新计算索引和事务日志写入。处理大型数据集时,仅更新将接收更改的行具有巨大的性能优势。

如果我们想在不必要的时候避免这些写入的开销,我们必须设计一种方法来检查是否需要更新。检查是否需要更新的一种方法是添加类似“where col <> 'hello'”的内容。

update table1 set col1 = 'hello' where col1 <> 'hello'

但在某些情况下,这不会很好地执行,例如,如果您要更新包含许多行的表中的多个列,并且实际上只有这些行的一小部分子集的值会发生更改。这是因为需要对所有这些列进行过滤,并且非等式谓词通常无法使用索引查找,以及如上所述的表和索引写入以及事务日志条目的开销。

但是有一个更好的替代方案,使用 EXISTS 子句与 EXCEPT 子句的组合。其想法是将目标行中的值与匹配源行中的值进行比较,以确定是否确实需要更新。查看下面修改后的查询并检查以 EXISTS 开头的附加查询过滤器。请注意 EXISTS 子句内部的 SELECT 语句没有 FROM 子句。该部分特别重要,因为这只会在查询计划中添加额外的常量扫描和过滤操作(两者的成本都很小)。因此,您最终得到的是一种非常轻量级的方法,用于确定是否需要更新,从而避免不必要的写入开销。

update table1 set col1 = 'hello'
/* AVOID NET ZERO CHANGES */
where exists
(
/* DESTINATION */
select table1.col1
except
/* SOURCE */
select col1 = 'hello'
)

当您使用文字值更新表中所有行的一个值时,与在原始问题中的简单场景中检查简单 WHERE 子句中的更新相比,这看起来过于复杂。但是,如果您要更新表中的多个列,并且更新源是另一个查询,并且您希望最大限度地减少写入和事务日志条目,则此技术非常有效。它的性能也比使用 <> 测试每个字段更好。

更完整的示例可能是

update table1
set col1 = 'hello',
col2 = 'hello',
col3 = 'hello'
/* Only update rows from CustomerId 100, 101, 102 & 103 */
where table1.CustomerId IN (100, 101, 102, 103)
/* AVOID NET ZERO CHANGES */
and exists
(
/* DESTINATION */
select table1.col1
table1.col2
table1.col3
except
/* SOURCE */
select z.col1,
z.col2,
z.col3
from #anytemptableorsubquery z
where z.CustomerId = table1.CustomerId
)

关于sql - 如果不同/更改则更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6677517/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com