mysql update多字段时引发的一个问题

 


 【1】问题描述

该问题已在mysql5.7  8.0 均已测试出现

create table test111(id int primary key auto_increment,a int ,b int);

update操作前          

  

 update操作后

  

同理(无论加不加主键索引,效果均如上图!)

我们发现,update多个列时,如果前一个列的值被改变,后一个列表达式中如果有引用到被改变列的值,那么是修改后的;

本来应该是 最终 a=15,b=30的,结果b=35了! 这并不是我们想要的结果;

【2】分析解决

(2.1)其他数据库会这样吗?不会

以mssql为例子

  

这里  a=a+2,b=b+a  ,这里的 b=b+a 是  a=a+2 操作之前的数据

oracle

  

与上面一样,这里就不解释了

(2.2)为什么mysql会这样?

无论我测试8.0/5.7 版本,都会这样;

核心是因为 mysql 有 mvcc ??(参考文档中的文章是这样说的)

  但我感觉,其实是因为

1.我感觉多列update

2.其实是拆成了 一个一个 update

(2.3)总结

1=》其他数据库:查出一版结果信息来后,锁定目标行数据加载到内存,然后引用次结果集上数据做计算

  =》一次性计算出所有结果=》生成的新结果集记录到脏页;

  =》注意这里的计算是整个多列update所有表达式都一起计算的;

2=》mysql数据库:查出一版结果信息来后,锁定目标行数据加载到内存,然后引用次结果集上数据做计算曹邹

  =》会从左到右的执行 update 的 多列更新,先最左边这个,也就是说性质是类似拆成了多个update的形式;

  如:

    update test11 set a = a+5,b = b+a where id=1;

    先执行 update test11 set a=a+5;

    =》然后再 update test11 set b=b+a;  会重新来一遍当前读,所以这里的 a 是上一个 a=a+5 之后的结果值了;

【3】解决方案

(方法1)如果有依赖其他列操作的update,那么则一列一列update

(方法2)反向计算回去:  

  常规:update test11 set a = a+5,b = b+a where id=1;

  反向计算回去:update test11 set a = a+5,b = b+a-5 where id=1;

【参考文档】

https://www.cnblogs.com/keme/p/13101115.html

posted @   郭大侠1  阅读(357)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示