找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2406

积分

0

好友

336

主题
发表于 8 小时前 | 查看: 0| 回复: 0

作为刚入职的新人,我及时响应了顾问在群内发起的请求:更新某条数据的特定字段值。

  • 检查相关业务逻辑
  • 定位到对应的业务表
  • 执行UPDATE语句
  • 结果却显示:Affected rows: 0

咦!没有记录被影响,难道是SQL写错了?再次检查数据,发现字段值的确已经更新过了。原来是客户方的IT同事已经先行处理。此刻内心只能暗叹一句。

这不禁让人疑惑:Affected rows: 0 的出现,难道意味着UPDATE操作在底层真的会先进行比较?这岂不是“脱裤子放屁”,多此一举?更值得深思的是,先比较再更新,会不会影响执行效率?

哈哈!我这十年苦练,终于等到出人头地的机会了?干脆重写底层,直接梭哈...优化代码,走上人生巅峰!等等!这么好的事,轮得到我吗(不禁忆起十年前的电信诈骗故事)?压了口杯中的冷茶,让自己冷静下来,还是仔细翻阅资料为妙。

MySQL在执行UPDATE操作时,确实会在内部进行数据比较。如果发现待更新的新值与记录中的旧值完全相同,在绝大多数情况下,它会优化掉这次不必要的物理写入操作,直接返回成功,并报告Affected rows: 0。

水落石出后,如同拨开云雾见青天。让我们来具体看看这个 比较后跳过机制 是如何工作的。

  1. 定位记录与获取旧值
    数据库引擎会基于WHERE条件(例如使用索引或全表扫描)定位到目标记录,我们可以将其视为 record[1](即旧值记录)。
  2. 构建新记录数据
    执行器根据SET子句中的赋值表达式,构建出新的记录数据 record[0]
  3. 关键比较步骤
    在服务器层,MySQL会逐字段比对record[0](新值)和record[1](旧值)的二进制内容。
  4. 判断与终止
    如果所有字段的二进制内容都完全一致,系统便判定此次更新未产生任何实际的数据变更。于是,整个更新流程会在此处提前终止。

一个典型的UPDATE语句示例如下:

UPDATE user_salary_mager
SET salary=1000
WHERE name = ucoding

接着划重点:提前终止更新流程,带来了显著的性能好处。存储引擎因此不需要进行以下一系列耗时操作:

  • 不需要:加锁
  • 不需要:写Undo Log
  • 不需要:修改数据页
  • 不需要:写Redo Log

这的确是提高性能最优的选择之一了。不过,技术也应该有温度啊!老板,涨工资!老板,涨工资!

点赞收藏动画图标

对数据库底层机制和性能优化感兴趣?欢迎在云栈社区与更多开发者交流探讨。




上一篇:MySQL 现状堪忧:代码提交停滞、123个CVE漏洞与性能倒退
下一篇:OpenCode AI绘制电气原理图实践:电机起保停控制电路生成指南
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-25 18:24 , Processed in 0.300885 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表