文章目录

  • sql语句的执行过程
  • 查询语句select的执行过程
  • 准备工作
  • 过程解析
  • 客户端
  • 连接器
  • 查缓存
  • 分析器
  • 优化器
  • 执行器
  • 更新语句update的执行过程
  • redo log
  • binlog
  • redo log 与binlog不同点


sql语句的执行过程

查询语句select的执行过程

准备工作

如我们通过执行界面创建一个表user

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL COMMENT '主键id',
  `name` varchar(50) NOT NULL COMMENT '用户名称',
  `phone` varchar(50) NOT NULL COMMENT '用户手机号',
  PRIMARY KEY (`id`),
  UNIQUE INDEX `idx_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入1条记录,

insert into user values(1,'张三','18790098898');

执行

select * from user;

结果

mysql> select * from user;
+----+--------+-------------+
| id | name   | phone       |
+----+--------+-------------+
|  1 | 张三   | 18790098898 |
+----+--------+-------------+
1 row in set (0.00 sec)

过程解析

一条简单的select语句大致有以下阶段:

  1. 客户端
  2. 连接器
  3. 查询缓存
  4. 分析器
  5. 优化器
  6. 执行器
  7. 存储引擎
客户端

执行mysql,在navicat,cmd,terminal等应用端执行sql

连接器

负责与客户端连接,建立,获取,维持连接等。
建立连接之后,默认维持时间为8小时,超时则会断开,由wait_timeout 控制

查缓存

如果查到结果则直接返回,否则执行第4-7步

MySQL 执行过的语句与结果会以 key-value 的结构缓存在内存中。key 是查询的语句,value 是查询的结果。
因此查询请求进入,会先到查询缓存,如果在缓存中有 key,则将value 就会被直接返回给客户端,否则执行后面的操作
注:
查询缓存只要有对一个表的更新,这个表上所有的查询语句对应的缓存都将清空。MySQL 8.0 版本不再支持查询缓存

分析器

主要有:语法分析,词法分析。
词法分析主要分析关键词有没有,是否存在,如select, where
语法分析主要分析sql语句是否满足sql的语法, 如关键词输错,join没有条件 on等

优化器

经过分析器后,mysql得知语句的执行内容,优化器的工作就是对执行内容进行一个优化,如多个索引决定使用哪个索引;有多表关联(join)的时候,决定哪个表是主表,哪个表是关联表。

执行器

执行器的工作为执行语句,使用存储引擎提供的接口。如调用存储引擎接口,取得第一行,判断是否满足条件的数据,是则存到结果集,不是则取下一行。

数据库的慢查询日志中看到一个 rows_examined 的字段,这个是调用存储引擎扫描的次数,实际上调用一次存储引擎,存储引擎内部可能扫描多次,因此 引擎扫描行数跟 rows_examined 不完全相同

整体执行流程图

引用自极客时间mysql实战45讲:学习连接

mysql循环输出uuid mysql循环执行sql语句_存储引擎


从整体流程图可看出,整体sql分2大块:server层和引擎层

更新语句update的执行过程

如我们要更改张三的手机号,执行语句为:

update user set phone =13790098898 where id =1;

执行成功

mysql> update user set phone =13790098898 where id =1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

查询结果

mysql> select * from user;
+----+--------+-------------+
| id | name   | phone       |
+----+--------+-------------+
|  1 | 张三   | 13790098898 |
+----+--------+-------------+
1 row in set (0.00 sec)

首先,查询语句的流程更新语句也同样会执行。在查询缓存的流程,更新的时候会将所有缓存结果清除,注:mysql 8.0不再支持缓存查询
除此之外,更新语句有两个重要的日志模块:redo log和binlog

redo log

  • redo log 为重做日志,或成为回滚日志,在InnoDB存储引擎层 才会有。其作用是提高sql更新效率。
  • 若每次执行更新语句,都要从磁盘查找到对应的记录,更新,并保存到磁盘中,若更新操作频繁,磁盘IO,查找的成本是很高的。
  • InnoDB引擎每次执行更新语句时,将记录写进redo log并且更新内存,当系统空闲的时候,会统一将redo log的记录更新到磁盘
  • InnoDB 的 redo log 是固定大小的,可以设置,redo log 通常有两个标志:write pos(当前写位置),checkpoint(要擦出的位置)。当更新一条记录,write pos会想checkpoint方向移动,当write pos要到达checkpoint位置时,标示redo log 内存已满,不能继续记录,要将redo log的记录更新到磁盘,并且清空redo log才能继续记录。

binlog

binlog 为server层的归档日志,由于mysql自带的存储引擎为MyISAM,MyISAM没有没有 crash-safe 的能力,binlog 日志只能用于归档。
而 InnoDB 以插件形式引入 MySQL 的,使用 redo log 来实现 crash-safe 。

redo log 与binlog不同点

待更新…