专栏名称: 飞总聊IT
飞总,从事大数据的基础构架研发10余年。本公众号的主要目的是和大家交流我在大数据基础架构,IT前沿发展,职场经验的方面的观点和看法。本公众号仅代表本人的观点,不代表公司观点。
目录
相关文章推荐
51好读  ›  专栏  ›  飞总聊IT

面试官:听说你sql写的挺溜的,你说一说查询sql的执行过程

飞总聊IT  · 公众号  ·  · 2020-04-11 09:00

正文



当希望Mysql能够高效的执行的时候,最好的办法就是清楚的了解Mysql是如何执行查询的,只有更加全面的了解SQL执行的每一个过程,才能更好的进行SQl的优化。

当执行一条查询的SQl的时候大概发生了一下的步骤:

  1. 客户端发送查询语句给服务器。

  2. 服务器首先检查缓存中是否存在该查询,若存在,返回缓存中存在的结果。若是不存在就进行下一步。

  3. 服务器进行SQl的解析、语法检测和预处理,再由优化器生成对应的执行计划。

  4. Mysql的执行器根据优化器生成的执行计划执行,调用存储引擎的接口进行查询。

  5. 服务器将查询的结果返回客户端。

Mysql的执行的流程图如下图所示:


这里以一个实例进行说明Mysql的的执行过程,新建一个User表,如下:

// 新建一个表
DROP TABLE IF EXISTS User;
CREATE TABLE `User` (
  `id` int(11NOT NULL AUTO_INCREMENT,
  `name` varchar(10DEFAULT NULL,
  `age` int DEFAULT 0,
  `address` varchar(255DEFAULT NULL,
  `phone` varchar(255DEFAULT NULL,
  `dept` int,
  PRIMARY KEY (`id`)
ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;

// 并初始化数据,如下
INSERT INTO User(name,age,address,phone,dept)VALUES('张三',24,'北京','13265543552',2);
INSERT INTO User(name,age,address,phone,dept)VALUES('张三三',20,'北京','13265543557',2);
INSERT INTO User(name,age,address,phone,dept)VALUES('李四',23,'上海','13265543553',2);
INSERT INTO User(name,age,address,phone,dept)VALUES('李四四',21,'上海','13265543556',2);
INSERT INTO User(name,age,address,phone,dept)VALUES('王五',27,'广州','13265543558',3);
INSERT INTO User(name,age,address,phone,dept)VALUES('王五五',26,'广州' ,'13265543559',3);
INSERT INTO User(name,age,address,phone,dept)VALUES('赵六',25,'深圳','13265543550',3);
INSERT INTO User(name,age,address,phone,dept)VALUES('赵六六',28,'广州','13265543561',3);
INSERT INTO User(name,age,address,phone,dept)VALUES('七七',29,'广州','13265543562',4);
INSERT INTO User(name,age,address,phone,dept)VALUES('八八',23,'广州','13265543563',4);
INSERT INTO User(name,age,address,phone,dept)VALUES('九九',24,'广州','13265543564',4);

现在针对这个表发出一条SQl查询: 查询每个部门中25岁以下的员工个数大于3的员工个数和部门编号,并按照人工个数降序排序和部门编号升序排序的前两个部门。

SELECT dept,COUNT(phone) AS num FROM User WHERE age25 GROUP BY dept HAVING num >= 3 ORDER BY num DESC,dept ASC LIMIT 0,2;

执行连接器

开始执行这条sql时,会检查该语句是否有权限,若是没有权限就直接返回错误信息,有权限会进行下一步,校验权限的这一步是在图一的连接器进行的,对连接用户权限的校验。

执行检索内存

相连建立之后,履行查询语句的时候,会先行检索内存,Mysql会先行冗余这个sql与否履行过,以此 Key-Value 的形式平缓适用内存中,Key是 检索预定 ,Value是 结果集

假如内存key遭击中,便会间接回到给客户端,假如没命中,便会履行后续的操作,完工之后亦会将结果内存上去,当下一次进行查询的时候也是如此的循环操作。

执行分析器

分析器主要有两步:(1) 词法分析 (2) 语法分析

词法分析主要执行 提炼关键性字 ,比如select, 提交检索的表 提交字段名 提交检索条件 。语法分析主要执行辨别你 输出的sql与否准确 ,是否 合乎mysql的语法

当Mysql没有命中内存的时候,接着执行的是 FROM student 负责把数据库的表文件加载到内存中去, WHERE age< 60 ,会把所示表中的数据进行过滤,取出符合条件的记录行,生成一张临时表,如下图所示。


GROUP BY dept 会把上图的临时表分成若干临时表,切分的过程如下图所示:


查询的结果只有部门2和部门3才有符合条件的值,生成如上两图的临时表。接着执行 SELECT后面的字段 ,SELECT后面可以是 表字段 也可以是 聚合函数

这里SELECT的情况与是否存在 GROUP BY 有关,若是不存在Mysql直接按照上图内存中整列读取。若是存在分别SELECT临时表的数据。







请到「今天看啥」查看全文