select 语句的执行流程

select 语句的执行流程

select * from stu where id = 10;

一条 Select 语句是如何在 MySQL 里面执行的呢?

为了了解过程,我们从大局观看起,从大局上可以更快理解知识,一些细节暂时忽略,后面文章在解释。

大体可以说,有两层,Service 层和存储引擎层。

Service 层

包括 连接器、查询缓存、分析器、优化器、执行器等。包括了很多的 MySQL 功能服务、内置函数(时间、日期、数学等),跨存储引擎也在这里实现,如存储过程,触发器、视图等。

存储引擎层

用于负责数据的存储和提取。支持多种存储引擎,早期是 MyISAM,MySQL 5.5 之后默认是 InnoDB 引擎。从图中我们可以知道,不同的存储引擎共用一个 Server 层。

下面是几种常见的存储引擎层对比。

过程

连接器

连接可以理解为,在 JDBC 中获取的 Connection 连接对象。因为要和数据库打交道,我们首先要与数据库进行连接。正如 HTTP 请求都要和服务器建立连接。

而数据库的连接器,就负责与外围打交道,和外面的客户端进行连接。在连接数据库的时候,首先遇到的就是数据库的连接器,来和你对接,我们常常在 cmd 的窗口中输入如下命令:

mysql -h$ip -P$port -u$user -p

然后就是开始输入数据库密码。

建立连接的过程是比较复杂的,建议是在使用中要尽量减少建立连接的动作(所以现场有很多连接池技术提供,阿里的、C3P0等等),也就是尽量使用长连接。

但是全部使用长连接后,有些时候 MySQL 占用内存涨得特别快,因为 MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 异常重启了。

查询缓存

为了提升数据库的性能,往往都会想到缓存技术。比如 MyBatis 有着自己的缓存技术。还有现在流行的 Redis 。而 MySQL 也有着自己的缓存,可以把查询过的数据缓存在内存中,以 Key-Value 的方式。每次查询的时候,在缓存中查找。

但是,不建议使用,因为往往对表的更新,会把该表对应的缓存都进行删除。那么好不容易建立起来的缓存,就没了。并且在 MySQL 8.0 的版本中,已经不在支持查询缓存。

分析器

学过编译原理的指的,对于语句的分析,分为词法分析,语法分析,语义分析。词法分析就是为了把 SQL 字符串解析处理,把 “select" 关键字识别出来,表 “stu” 识别为 stu 表,也就是关键字进行验证。

而语法分析就是分析语法是否有写错,是否满足 MySQL 语法,如果不满足则会报出 You have an error in your SQL syntax 错误,一般语法错误会提示第一个出现错误的位置,所以你要关注的是紧接“use near”的内容,语法分析还会在词法解析的基础上进一步的验证表名和字段名称的解析。

优化器

经历了分析器,那么 MySQL 就知道你要干啥了,那么怎么做?优化器完成了这一步,判断需要用哪个索引去查询、先执行哪个条件、或者决定 join 表的连接顺序等等,把前面的解析出来的换成执行的计划,进行最优评估。

执行器

最后到了执行,知道了要干啥、怎么做,执行器开始执行 SQL 语句。包括获取锁、打开表、获取数据。

但是开始前,会判断是否由查询的权限。如果没有返回权限错误。

ERROR 1142 (42000): SELECT command denied to user '1515'@'localhost' for table 'stu'

如果有权限,则打开表的,根据表的引擎定义,使用引擎提供的接口。如果我们这里的查询没有 ID 字段索引。那么执行器的流程是这样的

  1. 调用 InnoDB 引擎接口,读取表的第一行,判断 ID 是否为 10,不是跳过,是放在结果集中。
  2. 调用引擎接口,取下一行,重复相同的判断逻辑,直到取到这个表的最后一行。
  3. 执行器将上述遍历过程中满足条件的行组成记录集作为结果集返回给客户端。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值