查询SQL具体的执行流程

MySql的整体架构描述

img.png

img_1.png

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小时 。
    img_2.png
    一般项目中使用的连接池中的连接都是长连接的;(例如: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语句经过词法分析、语法分析后得到的抽象语法书如下:
img_3.png
注意,为了便于理解,抽象语法树中的关键字的Token用绿色表示,变量的Token用红色表示,灰色表示需要进一步拆分。

预处理器

预处理是用来对生成的 抽象语法树 进行语义校验,语义校验就是对查询的表、select投影列字段进行校验,判断表、字段是否存在等;

优化器

优化器的作用:主要是将SQL经过词法解析/语法解析后得到的语法树,通过MySQL的数据字典和统计信息的内容,经过 一系列运算 ,从而得出一个 执行计划

在优化过程中,经过的一系列运算是什么呢?下面简单说下:

  1. 逻辑变换:例如SQL的where条件中存在 8>9,那逻辑转换就是将语法树中存在的这种常量表达式直接进行化简,化简为 false;除了化简还有常量表达式计算等。
  2. 代价优化:就是通过付出一些数据统计分析的代价,来得到这个SQL执行是否可以走索引,以及走哪些索引;除此之外,在多表关联查询中,确定最终表join的顺序等;

在分析是否走索引查询时,是通过进行 动态数据采样统计分析 出来;只要是统计分析出来的,那就可能会存在分析错误的情况,所以在SQL执行不走索引时,也要考虑到这方面的因素。

  • MySql执行计划怎么查看呢?
    在执行的SQL语句前添加上 explain 关键字即可;

扩展: Oracle怎么查看执行计划? 参考此文章 Oracle通过执行计划查看查询语句是否使用索引

执行器

MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。
开始执行的时候,要先判断一下建立连接的对象对这个表有没有执行操作的权限,如果没有,就会返回没有权限的错误;如果有,就按照生成的执行计划进行执行。

通过文章最开始的架构图可知,执行器下面连接的就是存储引擎了,执行器就是通过调用存储引擎提供的API接口进行调用操作数据的。

存储引擎描述

存储引擎是对底层物理数据执行实际操作的组件,为Server服务器层提供各种操作数据的 API。MySQL 支持插件式的存储引擎,包括 InnoDB 、MyISAM、Memory 等。一般情况下,MySQL默认使用的存储引擎是 InnoDB 。

InnoDB 存储引擎支持的功能总览

img_4.png

扩展

其整体架构图:如下图所示,InnoDB存储引擎整体分为内存架构(Memory Structures)和磁盘架构(Disk Structures)。
img_5.png

深入学习,请参考此文章 你居然还不知道Mysql存储引擎InnoDB分为内存架构、磁盘架构?

评论