一条SQL查询语句执行流程
前言
本篇博客是林晓斌老师的《MySQL实战45讲》第二讲的总结。在第一讲的学习笔记中,介绍了一条查询语句的执行流程 —— 首先客户端与服务器连接,经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。在第二讲中,主要是介绍一条更新语句的执行流程。
一、sql语句执行流程
首先,创建一个表,这个表有一个主键 ID 和一个整型字段 c:
mysql> create table T(ID int primary key, c int);
-- 查询 ID=10 的语句
mysql> select * from T where ID=10;
-- 更新 ID=2 的一行数据
mysql> update T set c=c+1 where ID=2;
1.查询语句执行流程
执行查询语句前要先连接数据库,这是连接器的工作。
连接过后,会先在查询缓存中查找,是否有过查询记录,如果命中则直接返回结果。但在一个表上有更新的时候,跟这个表有关的查询缓存会失效,所以这条语句就会把表 T 上所有缓存结果都清空。所以,一般不建议使用查询缓存,且查询缓存在MySQL 8.0 之后被删掉了。
接下来,分析器会通过词法和语法解析知道这是一条更新语句。优化器决定要使用 ID 这个索引。然后,执行器负责具体执行,找到这一行,然后更新。
2.更新语句执行流程
与查询流程不一样的是,更新流程还涉及两个重要的日志模块,它们分别是: redo log(重做日志)和 binlog(归档日志)。其中,binlog属于Server层,redo log属于存储引擎。
二、redo log日志
1.赊账例子
酒店掌柜有一个粉板(redo log),专门用来记录客人的赊账记录。如果赊账的人不多,那么他可以把顾客名和账目写在板上。但如果赊账的人多了,粉板总会有记不下的时候,这个时候掌柜一定还有一个专门记录赊账的账本(磁盘)。
如果有人要赊账或者还账的话,掌柜一般有两种做法:
-
一种做法是直接把账本翻出来,把这次赊的账加上去或者扣除掉(直接写进磁盘);
-
另一种做法是先在粉板上记下这次的账(写入redo log),等打烊以后