03.11 Day 52 - insert 语句

news/2024/5/18 7:04:33

大家好,我是 Snow Hide,作为《MySQL 实战》这个专栏的学员之一,这是我打卡的第 52 天,也是我第 114 次进行这种操作。

今天我温习了该专栏里一篇叫《insert语句的锁为什么这么多?》的文章。

关键词总结:insert … select 语句(可重复读隔离级别下 binlog_format 为 statement 时执行插入操作时需要对表的所有行和间隙加锁)、insert 循环写入(循环插入语句执行过程、用临时表做优化)、insert 唯一键冲突(会话一执行回滚时会话三几乎同时发现死锁并返回的逻辑)、insert into … on duplicate key update(该语句的语义逻辑)。

 

所学总结:

 

insert … select 语句

可重复读隔离级别下 binlog_format 为 statement 时执行插入操作时需要对表的所有行和间隙加锁

  • 实际的执行效果是当会话二先执行时,由于该语句对表 t 主键索引加了 next-key lock,会在语句执行完成后,才允许会话一的 insert 语句执行;
  • 但如果没有锁的话,就会出现会话二的 insert 语句先执行,但事后写入 binlog 的情况。于是,在 binlog_format=statement 的情况下,binlog 里就记录了这样的语句序列:
insert into t values(-1,-1,-1);
insert into t2(c,d) select c,d from t;

 

insert 循环写入

insert into t(c,d)  (select c+1, d from t force index(c) order by c desc limit 1);

循环插入语句执行过程

  1. 创建有 c 和 d 两个字段的临时表;
  2. 按照索引 c 扫描表 t,依次取 c=4、3、2、1,然后回表,读到 c 和 d 的值写入临时表。此时 Rows_examined=4;
  3. 由于语义里有 limit 1,所以只取了临时表的第一行,再插入到表 t 中。这时 Rows_examined 的值加 1,变成了 5。

用临时表做优化

由于这个语句设计的数据量很小,可以考虑用内存临时表来做这个优化:

create temporary table temp_t(c int,d int) engine=memory;
insert into temp_t  (select c+1, d from t force index(c) order by c desc limit 1);
insert into t select * from temp_t;
drop table temp_t;

 

insert 唯一键冲突

会话一执行回滚时会话三几乎同时发现死锁并返回的逻辑

  1. 在事务一时启动会话一并执行 insert 语句,此时在索引 c 的 c=5 上加了记录锁。该索引是唯一索引,因此退化为记录锁;
  2. 在事务二时会话二要执行相同的 insert 语句,发现了唯一键冲突,加上读锁;同样地,会话三也在索引 c 上,c=5 记录上,加了读锁;
  3. 事务三时会话一回滚。这时会话二和会话三都试图继续执行插入操作,都要加上写锁。两个会话都要等待对方的行锁,所以就出现了死锁。
     

insert into … on duplicate key update

insert into t values(11,10,10) on duplicate key update d=100; 

该语句的语义逻辑

插入一行数据,当碰到唯一键约束就执行后面的更新语句。

 

末了

重新总结了一下文中提到的内容:insert … select 是很常见的在两表之间拷贝数据的方法、insert 和 select 的对象是同一个表时可能会造成循环写入、insert 语句如果出现唯一键冲突,会在冲突的唯一值上加共享的 next-key lock。


http://www.niftyadmin.cn/n/1895487.html

相关文章

72. 进程管理 - nice 和 renice 调整进程优先级

开篇词 使用 nice 和 renice 命令,我们可以在程序启动时指定其优先级,或更改运行中进程的优先级。 选项 nice 命令选项 这里是 nice 命令的一些选项: 选项描述-n 或 --adjustmentN将指定程序的优先级替换成数字 N。 renice 命令选项 …

Baeldung Java 周评 | 第七十一弹(关键词:将软件工件发布到 Maven Central、Hibernate 非限制读写缓存并发策略、IntStream 循环、原子变量与并发映射)

开篇词 尤金的第 71 篇 Java 周评,诞生了! Spring 以及 Java 相关 Java 8 / Spring 4 的采用情况如何? 我正在进行一项民意测验,以了解 Java 8 和 Spring 4 在整个行业中得到了怎样的采用。只需要几秒钟的投票时间&#xff0…

SpringBoot 2 构建多模块项目

开篇词 该指南向你展示如何使用 Spring Boot 创建一个多模块项目。该项目将具有一个库 jar 和使用该库的主应用。你还可以使用它来查看如何自行构建库(既不是应用的 jar 文件)。 你将创建的应用 我们将设置一个库 jar,它公开简单的 “He…

03.12 Day 53 - grant 和 flush privileges 语句

大家好,我是 Snow Hide,作为《MySQL 实战》这个专栏的学员之一,这是我打卡的第 53 天,也是我第 115 次进行这种操作。 今天我温习了该专栏里一篇叫《grant之后要跟着flush privileges吗?》的文章。 关键词总结&#…

73. 进程管理 - pmap 和 pstree 查看进程内存映射或进程树

开篇词 pmap 和 pstree 让我们可以查看进程的内存映射或树形显示进程信息。 选项 pmap 命令选项 这里是 pmap 命令的一些选项: 选项描述-x 或 --extended显示扩展格式。-d 或 --device显示设备格式。-q 或 --quiet隐藏头即脚信息。-A 或 --range low,high限制…

Baeldung Java 周评 | 第七十二弹(关键词:清理 ThreadLocal、集合转换、终极 JSON 库、Hibernate 读写缓存并发策略工作原理、JPA 原生 API 类型安全检查)

开篇词 尤金的第 72 篇 Java 周评,诞生了! Spring 以及 Java 相关 Spring 框架 4.2 进入 RC1 是的,Spring 4.2 在野外首次发布了候选版本。 我很兴奋的一件事是更好的事件支持。清理 ThreadLocal 何时使用(何时避免使用&…

SpringBoot 2 使用 Restdocs 创建 API 文档

开篇词 该指南将引导你在 Spring 应用中为 HTTP 端点生成文档。 你将创建的应用 我们将使用一些暴露 API 的 HTTP 端点构建一个简单的 Spring 应用。我们将使用 JUnit 和 Spring 的 MockMvc 仅测试网络层。然后,我们将使用相同的测试通过 Spring REST Docs 生成…

linux环境手动编译安装Nginx实践过程 附异常解决

为什么选择Nginx Nginx 是一个很牛的高性能Web和反向代理服务器, 它具有有很多非常优越的特性: 在高连接并发的情况下,Nginx是Apache服务器不错的替代品:Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一. 能够支持高达 50,000 个并发连接数的响应, 感谢…