业无高卑志当坚,男儿有求安得闲?这篇文章主要讲述#yyds干货盘点# 要修改值和原值相等,MySQL还会再执行update吗?相关的知识,希望能为你提供帮助。
创建一个简单的表user,并插入一行,然后对这一行做修改。
CREATE TABLE `users`
(
`id` int(11) NOT NULL primary key auto_increment,
`type`int(11) DEFAULT NULL
)
ENGINE = InnoDB;
insert into users
values (1, 2);
这时候,表t里有唯一的一行数据(1,2)。
假设,现在执行:
update users
set type=2
where id = 1;
会观察到:
仅从现象上看,mysql内部在处理这个命令的时候,可有如下选择:
①:更新都是先读后写,MySQL读出数据,发现type值本就是2呀,不更新,直接返回
②:MySQL调用InnoDB引擎提供的“修改为(1,2)”这个接口,但引擎发现值与原来相同,不更新,直接返回
③:InnoDB认真执行了“把这个值修改成(1,2)"这个操作,该加锁的加锁,该更新的更新
所以,当MySQL去更新一行,但是要修改的值跟原来的值相同,这时MySQL会选择:
- 简单暴力地执行一次修改
- 看到值相同了,就直接返回
- binlog_format=statement
- MySQL读出数据
- 发现:值 == 原来值
- 不更新
- 直接返回
Session 1 | Session 2 |
begin;
<
br>
update users set type=2 where id=1;
| |
update users set type=2 where id=1 (阻塞!) |
2 可见性验证MySQL调用InnoDB引擎提供的接口,但引擎发现值与原来相同,不更新,直接返回。
假设当前表里的值是(1,2):
S 1 | S 2 |
begin;
<
br>
select * from users where id=1;
// 返回(1, 2) | |
update users set type=3 where id=1;
| |
update users set type=3 where id=1;
<
br>
0 row affected | |
select * from users where id=1;
//返回(1,3) |
3 ?的想法
InnoDB认真执行“把这个值修改成(1,2)",该加锁的加锁,该更新的更新。
你会说MySQL咋这么蠢,就不会更新前判断一下值是否相同?这不是浪费InnoDB多更新一次吗?
其实MySQL已确认过。只是在这个语句里,MySQL认为读出来的值,只有一个确定的 (id=1),而要写的是(type=3),只从这两个信息看不出“无需修改”。
再看个实验。
4 可见性验证方式--对照
S 1 | S 2 |
begin;
<
br>
select * from users where id=1;
// 返回(1, 2) | |
update users set type=3 where id=1;
| |
update users set type=3 where id=1 and type=3;
<
br>
0 rows affected | |
select * from users where id=1;
//返回(1,2) |
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)
【#yyds干货盘点# 要修改值和原值相等,MySQL还会再执行update吗()】
推荐阅读
- APICloud平台使用融云模块实现音视频通话实践经验总结分享
- linux grep 如何搜索出包含某个字符串的所有文件 find
- Python Numpy库教程(超详细)
- linux c之出现warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration]这个问题
- RT-Thread快速入门-线程管理(下)
- linuxc之通过管道实现兄弟间进程通信()
- 90%的转型企业需要“零信任”
- JavaScript实现猫吃鱼小游戏
- 7.利用MySQL Router构建读写分离MGR集群 | 深入浅出MGR