SQL单条数据更新:先select再更新与直接更新哪个资源消耗更高
SQL单元素更新两种方案的资源消耗对比
核心结论
绝大多数业务场景下,先select查询判断再执行update的方案资源消耗更高,直接执行带条件的update是更优选择。
两种方案的开销明细
- 方案1:先查再改
至少产生两次数据库操作开销:- 首先执行一次select查询,需要走索引查找匹配行,业务侧发起请求的话还会多产生一次网络往返开销
- 确认需要更新后,再发起update请求,需要二次查找目标行、加行锁、写redo log、undo log,执行实际变更
哪怕最终不需要更新,也已经产生了一次完整的select查询开销。
- 方案2:直接执行带条件的update
仅产生一次数据库操作开销:
主流数据库(MySQL、PostgreSQL、SQL Server等)底层执行update时,会先自动比对待更新字段的原值和新值:如果两者完全一致,会直接跳过后续写操作,不会产生日志写入、索引变更、触发器触发等额外开销,最终开销和一次同条件的select查询基本持平。如果确实需要更新,也省去了第一次查询的开销。
极少数例外场景
仅当同时满足以下所有条件时,先查再改的开销可能更低:
- 更新的筛选条件没有可用索引,单次update需要全表扫描,开销极高
- 业务中99%以上的请求都不需要执行实际更新
- 可以通过带覆盖索引的select快速判断是否需要更新
该场景在实际业务中非常罕见,不具备普适性。
优化建议
可以直接在update的where条件里加上值不等的判断,进一步降低数据库底层的判断开销,示例:
-- 原更新逻辑:将id=123的用户昵称改为"新昵称" UPDATE user SET nickname = '新昵称' WHERE id = 123; -- 优化后:新增值不等判断,无需更新时数据库直接跳过执行 UPDATE user SET nickname = '新昵称' WHERE id = 123 AND nickname != '新昵称';
内容的提问来源于stack exchange,提问作者Tomas Palau
相关产品推荐
相关产品推荐

