Mysql基础架构:一条查询语句如何执行

MySQL是关系数据库,关系数据库,顾名思义,是建立在关系模型基础上的数据库,我们现实世界中的各种实体以及实体之间的各种联系一般可用关系模型来表示。经过数十年的发展,关系数据库在理论和工业实践中都已经发展到很成熟的地步,可以说,目前的绝大部分应用,使用MySQL都有成熟的解决方案。

数据库的架构一般可以分为应用层,逻辑层,物理层,MySQL也可以这样理解.

对应Mysql:

应用层,负责和客户端,用户交互,需要和不同的客户端和中间服务器进行交互,建立连接,记住连接的状态,响应它们的请求,返回数据和控制信息(错误信息,状态码等)。

逻辑层,负责具体的查询处理、事务管理、存储管理、恢复管理,以及其他的附加功能。查询处理器负责查询解析、执行,当接收到客户端的Sql查询,数据库就分配一个线程来处理它,由查询处理器生成执行计划,交由计划执行器来执行,执行器的部分操作还需要访问更底层的事务存储管理器操作数据,事务、存储管理器主要负责我们的事务管理、并发控制、存储管理,由我们的事务管理器来确保“ACID”特性,由锁管理器来控制我们的并发,由日志管理器来确保我们的数据持久化,存储管理器一般还包括一个bufer管理器,由它来确定磁盘和内存缓冲之间的数据传输。

物理层,实际物理磁盘(存储)上的数据库文件.如我们的数据文件、日志文件等。

我们可以先看Mysql官方提供基础架构图:

image.png

我们再看一下Mysql简化后逻辑架构图:

image.png

从图中可以看到,在逻辑层面大体可以分为Server层和存储引擎层两部分

Server层主要包括:连接器、分析器、优化器、执行器、查询缓存等。涵盖了MYSQL大多数核心功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。

存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。

不同的存储引擎共用一个Server层

  1. 连接器

连接器主要负责跟客户端建立连接、权限、维持和管理连接。

mysql -h$ip -P$port -u$username -p$password

MYSQL连接器建立连接后,即使你对当前用户进行权限修改也不会影响当前连接,等连接断开后重连才会重新进行权限校验。连接完成后,没有后续操作我们称作空闲连接,可以通过show processlist 命令查询空闲连接如下图:

image.png

MYSQL默认保持连接时间是8h,可以通过wait_timeout参数控制,建立连接是一个非常复杂过程,所以建议使用长连接方式。mysql执行过程中临时使用内存管理在连接对象里,只有在断开连接后才会释放,如果长时间保持连接容易发生OOM,解决方案如下:

 1.  定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。

 2.  如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。
复制代码
  1. 查询缓存

在mysql8版本之前,拥有查询缓存模块,每一个查询结果缓存到查询缓存中,下次同样的sql直接走缓存返回结果,一般默认查询语句不建议走缓存,因为缓存针对表,每一次对表的修改都会删除这个表上所有缓存,可以通过配置如下参数默认不走缓存,按需走缓存:

query_cache_type 设置为 DEMAND
select SQL_CACHE * from T where ID=10;//SQL_CACHE 显示指定当前sql走缓存
复制代码
  1. 分析器

mysql分析器通过拆解sql语句判断select、update、delete、insert,并且拆解from后面所对应的表以及where条件。通过拆解判断当前sql语句是否符合mysql规范,如果不规范就会抛出“You have an error in your SQL syntax”错误提示。

  1. 优化器

mysql优化器是决定当前sql如果有多个索引具体走哪个索引,如下:

select * from a join b useing(ID) where  a_id = 1;
复制代码

优化器会通过两表关联比较,假如a表数据少b表数据,优化器通过以a表为主表关联b表查询次数远远比选择b表关联a表次数少,查询结果一样但是执行效率不同,优化器会选择最优解,这里也是我们常说mysql优化最左原则、索引覆盖、索引下推等地方,我们可以通过explain查看sql执行计划来判断是否走索引。

  1. 执行器

mysql执行器就是实际执行sql地方,首先会进行权限校验判断是否拥有执行权限,然后分两种情况有无索引:

select * from a  where ID = 1;
复制代码

如果ID字段有索引,有索引走索引树根据条件判断快速遍历索引树命中索引,主键索引直接查询到数据存到结果集,继续执行下一个,普通索引会进行一次回表查询到结果存到结果集,遍历完索引树后把结果集返回给客户端

如果ID字段没有索引,调用innodb引擎接口取表中第一行判断是否符合条件,没有继续调用接口查询下一行,直到遍历完表中所有行,查询到的结果放到结果集中返回给客户端

小结:

本文介绍了mysql基础架构,以及重点介绍逻辑架构,让我们知道一条查询语句它在mysql中执行顺序,使我们对mysql执行流程有个初步印象,后面我会继续一步一步详细拆解mysql执行流程。

参考资料:

知乎 zhuanlan.zhihu.com/p/19965157

极客时间 mysql实战45讲

猜你喜欢

转载自juejin.im/post/7011276065792327688