【问题标题】:Which is more efficient update where or if exists then update哪个更有效的更新在哪里或如果存在然后更新
【发布时间】:2026-01-17 04:40:01
【问题描述】:

我想知道哪个更有效以及为什么。

if not exists (select 1 from table where ID = 101 and TT = 5)
begin
    update table 
    set TT = 5
    where ID = 101;
end;

update table 
set TT = 5
where ID = 101 and TT <> 5;

假设 ID 上有一个聚集索引(没有更多的表使用默认表创建设置)

【问题讨论】:

  • 看起来你可以很容易地测试自己
  • 取决于您是否有触发器,因为第二个版本将导致触发器运行。
  • @Charlieface 非常棒
  • 通常不会发布实际更新,但如果您使用SNAPSHOT,那么也会发布实际更新。 rowversion 也将在第二个版本中得到更新,GENERATED AS 列也是如此。
  • @Charlieface 没有触发器,但我不明白顶部的触发器如何不执行触发器。我假设只有当一行被更新时,触发器才会触发???如果没有更新行,底部的是否会执行触发器???

标签: sql-server tsql indexing


【解决方案1】:

【讨论】:

    【解决方案2】:

    SQL Server 通常optimize a non-updating UPDATE 不会实际发布任何更新。因此,使用简单的表格,您不会看到太大的差异。

    • 如果您有触发器,它们将在UPDATE 语句执行时被触发,与更新的行数无关。
      • 如果UPDATE 语句在行上执行,即使它们被修改为相同的值,它们也会出现在触发器中。
      • 如果使用WHERE 子句过滤掉行,例如and TT &lt;&gt; 5,则触发器将以 0 行触发
    • 无论如何,rowversionGENERATED AS 列都会更新。
    • 聚集键列会导致整行的删除和插入。
    • 如果ALLOW_SNAPSHOT_ISOLATIONREAD_COMMITTED_SNAPSHOT 处于打开状态,即使不使用,由于行版本控制的工作方式,将始终进行实际更新。
    • 如果IF EXISTS 很复杂,可能仍然不值得这样做,但在简单的情况下通常是这样。

    【讨论】: