ID列含聚集索引时,EXISTS判断后更新与带条件直接UPDATE哪个效率更高?
两种SQL更新写法的效率对比结论
在ID列建有聚集索引的前提下,第二种单句UPDATE写法的执行效率更高,具体原因如下:
两种写法回顾
第一种写法
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;
效率差异的核心原因
- 执行开销更低
第一种写法需要执行两次聚集索引查找:第一次是IF NOT EXISTS的查询判断,第二次是UPDATE的条件匹配,单次聚集索引查找虽然开销不高,但两次操作的累计开销必然高于第二种写法的单次索引查找。 - 避免无意义的写操作
第一种写法的UPDATE逻辑没有过滤TT已经等于5的场景,就算IF NOT EXISTS判断时TT不等于5,高并发场景下也可能出现判断后、更新前TT被其他事务改为5的情况,这时UPDATE还是会执行无意义的写操作,触发事务日志生成、数据页修改、甚至触发器执行等额外开销。而第二种写法是原子操作,只有TT确实不等于5的时候才会执行写操作,完全避免了这类无效开销。 - 优化器支持更好
单句UPDATE的结构更简单,数据库查询优化器可以直接生成最优执行计划,不需要处理分支逻辑的上下文开销,执行路径更短。
额外补充
第一种写法还存在逻辑竞态风险:两次操作之间的时间差可能导致数据更新不符合预期,第二种原子操作的写法不存在这类问题,正确性也更高。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

