MySql:一条SQL语句从客户端到服务端的执行流程简述

MySql:一条SQL语句从客户端到服务端的执行流程简述


前言

记录一条SQL语句从客户端到MySql服务端所执行经历的流程与部件的简要工作特性。

先放一张总体的流程图,再细分每一块的内容。

MySql:一条SQL语句从客户端到服务端的执行流程简述


执行流程:

1.连接Mysql

MySql:一条SQL语句从客户端到服务端的执行流程简述

  • 通信类型:同步通信
  • 连接类型:长连接/短连接都支持
  • 通信协议:Unix Socket(本地),TCP/IP
  • 通信方式:半双工

注意:客户端连接MySql服务时是半双工通信,客户端和服务端交互发送数据时必须一次发送完毕,在传输特别大的数据包时系统性能开销非常大,所以当客户端使用insert等语句发送大量的数据包时服务端就会拒绝连接,原因是服务端默认限制客户端发送的数据包大小不能超过4MB,这点可以通过修改MySql参数来更改大小限制,或者将需要发送的数据包在客户端进行分批发送处理。同理,在服务端返回给客户端数据时也要避免大量的数据包传输,所以要避免使用不带Limit的查询语句进行批量查询,或者可以先使用count做数据量预估,根据数据量进行分批查询。(注:现在很多客户端工具在使用select语句时会自动添加limit)

2.缓存与解析器

MySql:一条SQL语句从客户端到服务端的执行流程简述

  1. 缓存:这的缓存比较鸡肋,MySql 5.x的版本默认关闭,MySql 8.x的版本已废除。
  2. 解析器:词法分析,语法分析,生成解析树。

当缓存是打开的情况下,MySql服务端拿到Sql语句后,首先会到缓存判断是否有完全一致的Sql语句查询记录(判断时Sql语句连空格都不能有误差),有就将相应的结果集返回给客户端(这里还有个点,当数据库中的某条记录发生改变时,缓存中相应的数据集都会作废,所以很鸡肋。),当缓存中不存在时,会将Sql语句交给解析器来处理,解析器通过关键字将SQL语句进行解析,并生成一棵对应的“解析树”,接着会验证Sql语句是否有词法、语法等错误,例如,它将验证是否使用错误的关键字,或者使用关键字的顺序是否正确等,再或者它还会验证引号是否能前后正确匹配。下面放一张sql语句经过解析器生成的解析树:

MySql:一条SQL语句从客户端到服务端的执行流程简述

3.预处理器(Preprocessor)

MySql:一条SQL语句从客户端到服务端的执行流程简述

预处理器会对解析树进行进一步检查解析树是否合法,例如,这里将检查数据表和数据列是否存在,还会解析名字和别名,看看它们是否有歧义。接着预处理器会验证权限。这通常很快,除非服务器上有非常多的权限配置。

4.优化器(查询优化器 Query Optimizer)

MySql:一条SQL语句从客户端到服务端的执行流程简述

优化器是数据库中非常重要的一个部分,首先要明确一个问题,一条Sql语句并不是只有一种执行路径。当优化器拿到预处理器发来的解析树后,会根据解析树生成不同的执行路径,这些执行路径就是常说的执行计划(Execution Plan),优化器会对这些执行计划计算对应的开销(cost),当得到不同的执行计划与相应的开销后,优化器将它认为最佳的执行计划去交给下一个部件去执行。

优化器在一定程度上可以优化Sql语句,例如有关联查询使用Join时它可以选择使用哪张表作为基准数据表,或者一个Sql语句有用到多个索引时会由它会选择使用哪个索引,而优化器判断这些情况的标准就是cost。同时还要注意一点,优化器所认为的最佳的执行计划不一定准确,并且有优化器存在不代表我们就可以随便写Sql语句。

如果有对优化器执行过程与生成的执行计划感兴趣的同学,可以使用优化器追踪optimizer_trace来查看。

同时推荐一本书:《数据库查询优化器的艺术-原理解析与SQL性能优化》。

MySql:一条SQL语句从客户端到服务端的执行流程简述

5.查询执行引擎

MySql:一条SQL语句从客户端到服务端的执行流程简述

当优化器将执行计划交到查询执行引擎手里时,剩下的任务就简单多了,查询执行引擎调用相应的API接口来操作存储引擎,将存储引擎返回的查询结果返回给客户端,如果缓存开启的情况也会在缓存中进行缓存。

6.存储引擎

存储引擎就有很多了,像Mysql5.5版本前默认使用的MyIsan存储引擎,5.5版本后默认使用的InnoDB存储引擎,如果想了解不同Mysql支持的存储引擎可以到官网上查看,在官网上有详细列出不同存储引擎的特性,像比较奇葩的黑洞存储引擎。

不同存储引擎的特性与数据存储方式等各不相同,可以根据实际应用场景来为table选择合适的存储引擎。

(数据库有默认的存储引擎,但是表的存储引擎是可以替换的)


总结

一条普通的Sql语句基本的执行流程简单的记录了一下,每个环节都有更为丰富的实现细节,每个环节响应的设置参数在官网上都有明确的说明,学习的重点日后会偏向存储引擎的特性与原理。