mysql学习笔记(一)一条 SQL 查询语句是如何执行的

 基础架构:一条 SQL 查询语句是如何执行的?

截取一张丁奇大佬画的架构图

MySQL大致可以分为Server层和存储引擎层两部分。

Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数服务功能,

以及所有的内置函数,所有跨存储引擎的功能都在这一层实现,比如存储过程、视图等。

存储引擎层负责数据的存储和提取。支持InnoDB,MyISAM,Memory等多个存储引擎

从MySQL5.5.5开始默认存储引擎为InnoDB。

接下来根据下面的这条sql语句,依次观看每个组件的作用。

mysql> select * from T where ID=10 ;

连接器

第一步,你会连接到这个数据库上,接待你的就是连接器,连接器负责和客户端建立连接、获取权限、维持和管理连接。连接命令如下:

mysql -h ip地址 -P 端口号 -u 用户名 -p

执行命令后,输入密码。

连接命令中的mysql是客户端工具,用来跟服务器建立连接。完成经典的TCP握手后,连接器就会使用你输入的用户名和密码认证你的身份。

连接完成后,如果你没有后续动作,这个连接处于空闲状态,你可以使用show processlist命令查看。

mysql学习笔记(一)一条 SQL 查询语句是如何执行的_第1张图片

客户端如果太长时间没有动作,连接器就会自动将它断开,这个时间由参数wait_timeout设置,默认是8小时。

数据库里,长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。短连接是指每次执行完很少的几次查询就断开,下次查询再重新建立。

建立连接过程较复杂,尽量使用长连接,但是全部使用长连接,你有时会发现MySQL涨的特别快,这是因为

MySQL在执行过程中临时使用的内存是管理在连接对象里的,连接断开的时候才会释放资源,如果长连接累积下来可能造成内存占用太多,被系统强行杀掉,从现象看就是MySQL异常重启了。

那么怎么解决这个问题呢?

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

2.如果版本是5.7以上版本,可以在每次执行比较大的操作后,通过mysql_reset_connect来重新初始化连接资源。这个过程不需要重连和重新做权限验证,连接会恢复到刚创建完的状态。

查询缓存

连接建立后,就可以执行select语句了,执行逻辑会来到第二步:查询缓存。

mysql拿到查询请求后,会先到查询缓存看看,之前是否执行过这条语句。之前执行过的语句可能会以key-value对的形式缓存在内存中。key是查询的语句,value是查询的结果。如果你的查询能够在查询缓存中找到匹配的,那么对应的value会直接返回给客户端。

如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会存入查询缓存中,如果查询命中缓存,mysql不需要执行后面的复杂操作就能直接返回结果,效率很高。

但是大多数情况建议不要使用查询缓存?

因为弊大于利,查询缓存的失效非常频繁,只要有对一个表的更新,这个表上的所有查询缓存都会被清空。对于更新压力大的数据库,查询缓存的命中率会非常低。除非你的业务是一张静态表,很长时间才更新一次,比如:系统配置表,那么这张表上的查询才适合使用查询缓存。

配置方式:将参数query_cache_type设置成DEMAND,这样对于默认的sql语句都不使用查询缓存。对于确定要使用的语句,可以用 SQL_CACHE显示指定,范例如下:

select  SQL_CACHE * from S where sid = 1;

注意8.0版本开始,查询缓存的整块功能都被删掉了。

分析器

如果没有命中缓存就开始真正执行语句了。

首先要想让mysql知道你要做什么,因此需要对MySQL语句做解析。

分析器首先做“词法分析”。识别出里面的字符串分别是什么,代表什么。

接下来进行语法分析。根据语法分析的规则,判断SQL语句是否符合语法格式。

优化器

经过了分析器,MySQL就知道你要做什么了。在开始执行之前,还要先经过优化器的处理。

优化器是在表里有多个索引时,决定使用哪个索引;或者一个语句有多表关联时,决定各表的连接顺序。

不同的执行方法效率不同,逻辑结果相同,优化器的作用就是决定使用哪一个方案。

执行器

经过优化器的优化后,进入执行阶段,执行器开始执行语句。

开始执行的时候,先要判断你对这个表有没有执行某个操作的权限,

如果有权限,就打开表继续执行。打开表的时候,执行器会根据表的引擎定义,去使用这个引擎提供的接口执行操作。

 

你可能感兴趣的:(MySQL学习笔记)