MySQL各组件的作用(连接器/分析器/优化器/执行器/存储引擎/查询缓存)

MySQL鸟瞰图

MySQL由

  1. 连接器
  2. 查询缓存(8.0版本之前)
  3. 分析器
  4. 优化器
  5. 执行器
  6. 存储引擎

所组成。


1. 连接器:

连接器负责管理连接的【创建、维持、管理】以及【权限验证】。
执行SQL语句之前,客户端需要先与服务器进行连接,即:

mysql -u root -p

此时客户端会与MySQL服务器之间进行TCP三次握手建立连接(传输层),在TCP连接建立后,再进行MySQL客户端权限验证(应用层),此时可能会出现两种情况:
(1)MySQL用户名或者密码错误,此时客户端收到“Access denied for user”,随后客户端结束执行;
(2)用户名和密码验证通过,这时连接器会在【权限表】里查出此客户端拥有的权限(root、可读、可写等)。【权限的验证是在连接建立时进行的,连接之后即使修改用户权限也不会起作用,需要重连才会生效】

自动断开:
客户端持续一段时间没有读写操作,服务端需断开连接,默认8小时。

长连接与短连接:
长连接: 指连接建立后不会断开;
短连接: 每次指令执行完就断开连接,下次再操作需要重连(例如一次数据库查询就连接一次)。

长连接与短连接的利弊:
创建连接的过程复杂开销较大,所以提倡尽量使用长连接,以减少创建连接的次数。
但是长连接会导致内存开销较大,因为MySQL在执行过程中临时使用的内存全部存储在连接对象里面,时间久了就会积累大量内存,解决方法是由客户端定期断开长连接。服务端也有周期性的强制断开长连接的机制。

2.查询缓存:

连接建立权限验证通过后,就可以进行查询了(select语句)。
查询操作会首先进入查询缓存,查询缓存是 key-value 的形式,key是输入的查询语句,value是查询结果。
如果能命中,查询缓存直接返回结果给客户端;
如果没有命中,则执行后面的操作,在后面的操作中查到结果后,先把结果放到查询缓存中,再返回给客户端。

8.0版本已经将此功能删除,原因是查询缓存很容易失效,结果关联的表只要有任何更新就会导致缓存失效。

例如,数据库中有runoob_tb1、runoob_tb2等多个表,此次查询runoob_tb1表中的结果,查询后将结果保存到缓存中(select * from runoob_tb1)。随后,如果runoob_tb1进行了任何更新(delete/update/alter等),关于runoob_tb1表的所有缓存将全部失效。

因此,缓存的一大堆,常常因为一个语句就全部失效,对于大多数应用都是得不偿失的,所以MySQL取消了查询缓存的功能。

3.分析器:

如果查询缓存中没有查到,就开始真正的SQL语句分析了。
分析器负责对客户端输入的SQL语句进行词法分析,语法校验(例如select是不是少了一个s,关键字是否正确,要进行何种操作,是要查询还是要更新还是要删除),校验表名、字段名等(例如runoob_tb1这个表是否真的存在)。

4.优化器:

通过分析器的处理后,MySQL已经知道了客户端要做什么(select/update/delete),接下来优化器负责考虑怎样更高效的执行指令(例如索引的选择,基准表的确定等)。经过优化器后,SQL的执行计划就确定下来了。

5.执行器:

开始正式执行SQL语句之前,要先进行用户权限验证(如果是在查询缓存中直接返回,则是在返回结果时做权限验证)。
权限验证必须放在执行器这一步,不能放在优化器或更前,原因是SQL语句的操作不仅仅是SQL语句字面上的那些,例如如果有一个触发器,则只能在执行的过程中才能确定,优化器之前的阶段是无能为力的。(Q:什么是触发器?)

权限验证通过之后,就打开表继续执行,执行器会根据表的引擎的定义,去使用这个引擎提供的接口。

例如,对于一个没有索引的表,则先查询表的第一行,如果不符合,则再查询下一行,以此类推;
对于一个有索引的表,执行的逻辑也差不多,第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口。


参考链接:
https://www.jianshu.com/p/5b60de98332b

猜你喜欢

转载自blog.csdn.net/ArtAndLife/article/details/109755919
今日推荐