MySQL在update发现要修改值跟原值相同,会再执行修改吗?
2023-09-27 14:19:47 时间
当MySQL去更新一行,但是要修改的值跟原来的值是相同的,这时候MySQL会真的去执行一次修改吗?还是看到值相同就直接返回呢?
❌的想法一
MySQL读出数据=》发现值与原来相同=》不更新=》直接返回=》执行结束。
做一个锁实验来确认。
假设,当前表t里的值是(1,2)。
- 锁验证方式
sessionB的update被阻塞,加锁这个动作是InnoDB才能做的,所以排除该选项
❌的想法二
MySQL调用InnoDB引擎提供的接口,但引擎发现值与原来相同,不更新,直接返回。
假设当前表里的值是(1,2)。
- 可见性验证方式
sessionA的第二个select语句是一致性读(快照读),它看不见session B的更新。
现在它返回(1,3),表示它看见了某个新版本,这个版本只能是session A自己的update语句做更新的时候生成。
所以答案是
✅的想法
InnoDB认真执行了“把这个值修改成(1,2)"这个操作,该加锁的加锁,该更新的更新。
你肯定觉得MySQL怎么这么笨,就不会更新前判断一下值是不是相同?不就不用浪费InnoDB多更新一次了?
其实MySQL确认过了。只是在这个语句里面,MySQL认为读出来的值,只有一个确定的 (id=1), 而要写的是(a=3),只从这两个信息是看不出来“不需要修改”的。
再看个验证例子。
- 可见性验证方式–对照
上面的验证结果都是在 binlog_format=statement 格式下进行的。
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.02 sec)
mysql> show variables like 'binlog_row_image';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| binlog_row_image | FULL |
+------------------+-------+
1 row in set (0.02 sec)
如果是binlog_format=row 且binlog_row_image=FULL,由于MySQL需要在binlog里面记录所有字段,所以在读数据时,就会把所有数据读出来。
根据上面规则,“既然读了数据,就会判断”, 因此这时,
select * from t where id=1
结果就是 (1,2)。
同理,若是binlog_row_image=NOBLOB, 会读除blob外的所有字段,在这个例子,结果还是(1,2)。
对应代码如下,MySQL 5.6引入
- binlog_row_image=FULL读字段逻辑
如果binlog是row格式,并且image=full。那么read_set设为全1,表示所有的字段都要读
类似的,如果表中有timestamp字段而且设置自动更新,则更新“别的字段”的时候,MySQL会读入所有涉及的字段,这样通过判断,就会发现不需要修改。
相关文章
- mysql 查询优化执行过程
- mysql对执行结果进行html格式的输出?输出html格式?
- mysql中如何在命令行中,执行一个SQL脚本文件?
- Visual Studio 2017 - Windows应用程序打包成exe文件(2)- Advanced Installer 关于Newtonsoft.Json,LINQ to JSON的一个小demo mysql循环插入数据、生成随机数及CONCAT函数 .NET记录-获取外网IP以及判断该IP是属于网通还是电信 Guid的生成和数据修整(去除空格和小写字符)
- MySQL 执行计划
- mysql常用命令有什么
- mysql执行计划
- 《MySQL DBA修炼之道》——导读
- 【MySQL进阶-10】深入理解redolog,undolog和binlog的底层原理
- mysql索引有哪些类型?
- MySQL的S语法的执行顺序
- mysql的binlog进行数据恢复
- mysql 的编写顺序和执行顺序
- 基于PHP+MySQL实现在线考试系统【100010717】
- MySQL 物理组成-一条更新语句是如何执行的
- Django+Bootstrap+Mysql 搭建个人博客(二)
- Linux服务器制定mysql数据库备份的计划任务
- MySQL数据库:SQL语句的执行过程
- Linux中连接mysql执行sql文件
- Mysql执行计划
- MySQL计划任务(事件调度器)(Event Scheduler) 创建时 会执行一次
- 如果使用EntityFramework6链接Mysql
- 由浅入深探究mysql索引结构原理、性能分析与优化
- MYSQL 监控数据库SQL语句 查看数据库执行语句
- 使用mysqlbinlog从二进制日志文件中查询mysql执行过的sql语句 (原)
- MySQL - 一条SQL在MySQL中是如何被执行的?