查询SQL具体的执行流程
MySql的整体架构描述
Server层各节点描述
Server层中主要由 连接器、查询缓存、解析器/分析器、优化器、执行器
连接器
客户端想要对数据库进行操作时,前提是与数据库建立好连接;而连接器就是用来负责跟客户端建立连接、获取权限、维持和管理连接的。
连接方式:
- 短连接就是操作完毕后,马上close关掉。
- 长连接可以保持打开,减少服务端创建和释放连接的消耗,后面的程序访问的时候还可以使用这个连接。 一般我们会在连接池中使用长连接。
长连接使用时的注意事项:
客户端与服务器建立长连接,默认有效时间是 8小时 ,超过8小时MySql服务器就会将连接断开了,那么客户端再次请求的话,就会报 连接已断开的问题 ;
并且保持长连接会消耗内存。长时间不活动的连接,MySQL服务器会断开。查看长连接的超时时间
1
2
3
4
5-- 非交互式超时时间,如 JDBC 程序
show global variables like 'wait_timeout';
-- 交互式超时时间,如数据库工具
show global variables like' interactive_timeout';执行后得到下图结果:默认都是28800秒,8小时 。
一般项目中使用的连接池中的连接都是长连接的;(例如:druid、c3p0、dbcp等)长连接超时断的解决方案
- 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。
- 如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。
查询缓存
MySQL缓存是默认关闭的,也就是说不推荐使用缓存,为什么呢?
MySql为什么默认不开启缓存呢?
主要是由于它的使用场景限制的:- 缓存中数据存储格式:key(sql语句)-value(数据值);所以如果SQL语句(key)只要存在一点不同之处就会直接进行数据库查询了;
- 由于表中的数据不是一成不变的,大多数是经常变化的,而当数据库中的数据变化了,那么相应的与此表相关的缓存数据就需要移除掉;
MySQL 8.0 版本直接将查询缓存的整块功能删掉了。
解析器/分析器
分析器的工作主要是对要执行的SQL语句进行解析,最终得到抽象语法书,然后再使用预处理器判断抽象语法树中的表是否存在,如果存在的话,在接着判断select投影列字段是否在表中存在等。
- 词法分析
词法分析用于将SQL拆解为不可再分的原子符号,称为Token。并根据不同数据库方言所提供的字典,将其归类为关键字,表达式,字面量和操作符。 - 语法分析
语法分析就是根据词法分析拆解出来的Token(原子符号)将SQL语句转换为抽象语法树。下面就直接举例说明,看一个SQL它的抽象语法书到底长神魔样:
SQL语句:
1 | SELECT id, name FROM t_user WHERE status = 'ACTIVE' AND age > 18 |
然后上面的SQL语句经过词法分析、语法分析后得到的抽象语法书如下:
注意,为了便于理解,抽象语法树中的关键字的Token用绿色表示,变量的Token用红色表示,灰色表示需要进一步拆分。
预处理器
预处理是用来对生成的 抽象语法树 进行语义校验,语义校验就是对查询的表、select投影列字段进行校验,判断表、字段是否存在等;
优化器
优化器的作用:主要是将SQL经过词法解析/语法解析后得到的语法树,通过MySQL的数据字典和统计信息的内容,经过 一系列运算 ,从而得出一个 执行计划
。
在优化过程中,经过的一系列运算是什么呢?下面简单说下:
- 逻辑变换:例如SQL的where条件中存在 8>9,那逻辑转换就是将语法树中存在的这种常量表达式直接进行化简,化简为 false;除了化简还有常量表达式计算等。
- 代价优化:就是通过付出一些数据统计分析的代价,来得到这个SQL执行是否可以走索引,以及走哪些索引;除此之外,在多表关联查询中,确定最终表join的顺序等;
在分析是否走索引查询时,是通过进行 动态数据采样统计分析 出来;只要是统计分析出来的,那就可能会存在分析错误的情况,所以在SQL执行不走索引时,也要考虑到这方面的因素。
- MySql执行计划怎么查看呢?
在执行的SQL语句前添加上 explain 关键字即可;
扩展: Oracle怎么查看执行计划? 参考此文章 Oracle通过执行计划查看查询语句是否使用索引
执行器
MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。
开始执行的时候,要先判断一下建立连接的对象对这个表有没有执行操作的权限,如果没有,就会返回没有权限的错误;如果有,就按照生成的执行计划进行执行。
通过文章最开始的架构图可知,执行器下面连接的就是存储引擎了,执行器就是通过调用存储引擎提供的API接口进行调用操作数据的。
存储引擎描述
存储引擎是对底层物理数据执行实际操作的组件,为Server服务器层提供各种操作数据的 API。MySQL 支持插件式的存储引擎,包括 InnoDB 、MyISAM、Memory 等。一般情况下,MySQL默认使用的存储引擎是 InnoDB 。
InnoDB 存储引擎支持的功能总览
扩展
其整体架构图:如下图所示,InnoDB存储引擎整体分为内存架构(Memory Structures)和磁盘架构(Disk Structures)。
深入学习,请参考此文章 你居然还不知道Mysql存储引擎InnoDB分为内存架构、磁盘架构?