来自:非科班的科班

当希望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(11) NOT NULL AUTO_INCREMENT,`name` varchar(10) DEFAULT NULL,`age` int DEFAULT 0,`address` varchar(255) DEFAULT NULL,`phone` varchar(255) DEFAULT 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 age< 25 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临时表的数据。

最后生成的临时表如下图所示:


紧接着执行HAVING num>2过滤员工数小于等于2的部门,对于WHEREHAVING都是进行过滤,那么这两者有什么不同呢?

第一点是WHERE后面只能对表字段进行过滤,不能使用聚合函数,而HAVING可以过滤表字段也可以使用聚合函数进行过滤。

第二点是WHERE是对执行from USer操作后,加载表数据到内存后,WHERE是对原生表的字段进行过滤,而HAVING是对SELECT后的字段进行过滤,也就是WHERE不能使用别名进行过滤

因为执行WHERE的时候,还没有SELECT,还没有给字段赋予别名。接着生成的临时表如下图所示:


最后在执行ORDER BY后面的排序以及limit0,2取得前两个数据,因为这里数据比较少,没有体现出来。最后生成的结果也是如上图所示。接着判断这个sql语句是否有语法错误关键性词与否准确等等。

执行优化器

查询优化器会将解析树转化成执行计划。一条查询可以有多种执行方法,最后都是返回相同结果。优化器的作用就是找到这其中最好的执行计划

生成执行计划的过程会消耗较多的时间,特别是存在许多可选的执行计划时。如果在一条SQL语句执行的过程中将该语句对应的最终执行计划进行缓存。

相似的语句再次被输入服务器时,就可以直接使用已缓存的执行计划,从而跳过SQL语句生成执行计划的整个过程,进而可以提高语句的执行速度。


MySQL使用基于成本的查询优化器。它会尝试预测一个查询使用某种执行计划时的成本,并选择其中成本最少的一个。

执行执行器

由优化器生成得执行计划,交由执行器进行执行,执行器调用存储引擎得接口,存储引擎获取数据并返回,结束整个查询得过程。

这里之讲解了select的过程,对于update这些修改数据或者删除数据的操作,会涉及到事务,会使用两个日志模块,redo log和binlog日志。具体对这两个日志的介绍请看着一篇文章[深入mysql的innodb存储引擎之文件结构]。

以前的Mysql的默认存储引擎MyISAM引擎是没redo log的,而现在的默认存储引擎InnoDB引擎便是透过redo 复杂度来拥护事务的,保证事务能够准确的回滚或者提交,保证事务的ACID。

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:

长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

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

  1. 面试官让我手写一个生产者消费者模式?

    不知道你是否遇到过面试官让你手写生产者消费者代码.别说,前段时间有小伙伴还真的遇到了这种情况,当时是一脸懵逼. 但是,俗话说,从哪里跌倒就要从哪里爬起来.既然这次被问到了,那就回去好好研究一下,争取下 ...

  2. 面试官系统精讲Java源码及大厂真题 - 26 惊叹面试官:由浅入深手写队列

    26 惊叹面试官:由浅入深手写队列 人生的价值,并不是用时间,而是用深度去衡量的. 引导语 现在不少大厂面试的时候会要求手写代码,我曾经看过一个大厂面试时,要求在线写代码,题目就是:在不使用 Java ...

  3. 面试官的信(写给面试者)-----

    面试官的信(写给面试者)-----(转贴) (这是一篇很实用的文章,用一个面试官的口吻对学生求职面试进行了阐述,如果你要求职而又不知道该怎样做的话,那么,你需要看一看这篇文章咯) 今天的面试,我给每个 ...

  4. 一条SQL查询语句的执行过程,一张图说清SQL查询语句执行过程

    一张图说明 一条SQL查询语句的执行过程 一条sql语句从发送到数据库到它执行完成并返回结果,主要经历以下几个过程: 连接器->查询缓存(如果开启了查询缓存,则会经过这一步,但是大多数情况下都是 ...

  5. 当面试官让你手写防抖、节流时,是在考察什么

    防抖.节流,都是用于节省函数调用次数的方案,达到优化程序.提升性能甚至是避免bug的目的.作为一个经典的主题,也是面试常考项,部分面试官会让你手写,这时, 他是在考察什么?你能轻易地写出比较好的防抖. ...

  6. 7年工作经验,面试官竟然让我写算法题?

    有一位阿里工程师在脉脉上吐槽:自己明明有着BAT的5年工作经验,却没想到在应聘Hulu时,败在了算法题上. 明明有多年大厂工作经验,为什么还要在找工作跳槽时,面对算法的考题?    01  为啥美国的 ...

  7. 讲mysql执行流程书籍_MySQL 基础架构 1. 一条SQL查询语句的执行过程(个人学习笔记)...

    MySQL的逻辑架构图: MySQL 大体分为 "server 层" 和 "存储引擎层" 两部分: Server 层 包括 连接器.查询缓存.分析器.优化器.执 ...

  8. 面试官:请手写一个带取消功能的延迟函数,axios 取消功能的原理是什么

    大家好,我是若川.最近组织了源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步.同时极力推荐订阅我写的<学习源码整体架构系列> ...

  9. Java面试手写编程题(面试官经常让人手写)

    代码与编程题 135.写一个Singleton出来 Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 一般Singleton模式通常有几种种形式: 第一种形 ...

最新文章

  1. 对齐内容验证码和图片
  2. 菜渣初探mongodb--笔记篇
  3. gRPC in ASP.NET Core 3.0 -- 前言
  4. php将get传参解析成数组,php解析url (parse_url) 参数成数组 (parse_str)
  5. linux修改hostname
  6. ELK学习总结(2-5)elk的版本控制
  7. Flex移动性能检查列表
  8. js中做数字运算时出现的异常,期望值比实际值小太多太多
  9. window.onerror=hide_error_message;
  10. C语言俄罗斯方块代码
  11. 常用的浏览器及其内核
  12. 项目研发过程中甲方要增加合同外的需求,项目经理该如何处理?
  13. [MATLAB]代数/常微分求解(solve/dsolve)
  14. 当今世界最NB的25位大数据科学家
  15. (转)深度学习中各种图像库的图片读取方式
  16. C/C++后台开发基础知识
  17. 知识图谱 01:知识图谱概述
  18. android给图片加水印的极简实现方式
  19. SQLyog数据库列表(对象浏览器)字体大小设置方法,不是普通字体大小设置
  20. 解决MATLAB绘图延迟问题的一种方法

热门文章

  1. 单调栈 or 线段树扫描线 ---- E. Delete a Segment [单调栈+二分] [扫描线处理空白位置的技巧乘2]
  2. HDU2196[树形dp+二次扫描]java和c++版本题解
  3. java split array_Java如何循环数组并使用Split
  4. Codeforces Round #700 (Div. 2) A ~ E ,6题全,超高质量良心题解【每日亿题】2021/2/8
  5. 数据结构c语言函数大全,数据结构习题库(c语言版).doc
  6. 7-5 符号配对 (20 分)
  7. 化验室计算机用户管理,计算机实验室管理思路及方法
  8. etc下没有mysql_我在linux下,安装mysql的时候,cp support-files/my-medium.cnf /etc/my.cnf找不到my-medium.cnf...
  9. 小猿圈之学习java web需要有什么基础?
  10. 结对编程项目作业-设计文档