Mysql查询语句执行原理

数据库查询语句如何执行?
语法分析:首先进行语法分析,对使用sql表示的查询进行语法分析,生成查询语法分析树。
语义检查:检查sql中所涉及的对象以及是否在数据库中存在,用户是否具有操作权限等
视图转换:将语法分析树转换成关系代数表达式,称为逻辑查询计划;
查询优化:在选择逻辑查询计划时,会有多个不同的表达式,选择最佳的逻辑查询计划;
代码生成:必须将逻辑查询计划转换成物理查询计划,物理查询计划不仅能指明要执行的操作,也给出了这些操作的执行顺序,每步所用的算法,存储数据的方式以及从一个操作传递给另一个操作的方式。
将DML转换成一串可执行的存取操作的过程称为束缚过程。

Mysql查询语句执行过程
这里简单介绍一下mysql数据库,mysql数据库是一款关系型数据库,所谓关系型数据库就是以二维表的形式存储数据,使用行和列方便我们对数据的增删改查。

这篇博客,我们以mysql数据库为例,对一条sql语句的执行流程进行分析。(本篇博客不涉及到表连接)

首先,创建一张student表,字段有自增主键id,学生姓名name,学科subject,成绩grade

建表语句:

DROP TABLE IF EXISTS student;
CREATE TABLE `student` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
`subject` varchar(10) DEFAULT NULL,
`grade` double(4,1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;

初始化数据:

INSERT INTO student(`name`,`subject`,grade)VALUES('aom','语文',88);
INSERT INTO student(`name`,`subject`,grade)VALUES('aom','数学',99);
INSERT INTO student(`name`,`subject`,grade)VALUES('aom','外语',55); INSERT INTO student(`name`,`subject`,grade)VALUES('jack','语文',67);
INSERT INTO student(`name`,`subject`,grade)VALUES('jack','数学',44);
INSERT INTO student(`name`,`subject`,grade)VALUES('jack','外语',55); INSERT INTO student(`name`,`subject`,grade)VALUES('susan','语文',56);
INSERT INTO student(`name`,`subject`,grade)VALUES('susan','数学',35);
INSERT INTO student(`name`,`subject`,grade)VALUES('susan','外语',77); INSERT INTO student(`name`,`subject`,grade)VALUES('alice','语文',88);
INSERT INTO student(`name`,`subject`,grade)VALUES('alice','数学',77);
INSERT INTO student(`name`,`subject`,grade)VALUES('alice','外语',100); INSERT INTO student(`name`,`subject`,grade)VALUES('rajo','语文',33);
INSERT INTO student(`name`,`subject`,grade)VALUES('rajo','数学',55);
INSERT INTO student(`name`,`subject`,grade)VALUES('rajo','外语',55);

下面我们来看一下,数据在数据库中的存储形式。

  (图1.0)

现在针对这张student表中的数据提出一个问题:要求查询出挂科数目多于两门(包含两门)的前两名学生的姓名,如果挂科数目相同按学生姓名升序排列。

下面是这条查询的sql语句

SELECT `name`,COUNT(`name`) AS num FROM student WHERE grade < 60 GROUP BY `name` HAVING num >= 2 ORDER BY num DESC,`name` ASC LIMIT 0,2;

执行结果:

以上这条sql语句基本上概括了单表查询中所有要注意的点,那么我们就以这条sql为例来分析一下一条语句的执行流程。

1,一条查询的sql语句先执行的是 FROM student 负责把数据库的表文件加载到内存中去,如上图所示。(mysql数据库在计算机上也是一个进程,cpu会给该进程分配一块内存空间,在计算机‘服务’中可以看到,该进程的状态)

2,WHERE grade < 60,会把(图1.0)所示表中的数据进行过滤,取出符合条件的记录行,生成一张临时表,如下图所示。

  图(1.3)

3,GROUP BY `name`会把图(1.3)的临时表切分成若干临时表,我们用下图来表示内存中这个切分的过程。

        

4,SELECT 的执行读取规则分为sql语句中有无GROUP BY两种情况。

  (1)当没有GROUP BY时,SELECT 会根据后面的字段名称对内存中的一张临时表整列读取。

  (2)当查询sql中有GROUP BY时,会对内存中的若干临时表分别执行SELECT,而且只取各临时表中的第一条记录,然后再形成新的临时表。这就决定了查询sql使用GROUP BY的场景下,SELECT后面跟的一般是参与分组的字段和聚合函数,否则查询出的数据要是情况而定。另外聚合函数中的字段可以是表中的任意字段,需要注意的是聚合函数会自动忽略空值。

  我们还是以本例中的查询sql来分析,现在内存中有四张被GROUP BY `name`切分成的临时表,我们分别取名为 tempTable1,tempTable2,tempTable3,tempTable4分别对应上图,下面写四条"伪SQL"来说明这个查询过程。

SELECT `name`,COUNT(`name`) AS num FROM tempTable1;
SELECT `name`,COUNT(`name`) AS num FROM tempTable2;
SELECT `name`,COUNT(`name`) AS num FROM tempTable3;
SELECT `name`,COUNT(`name`) AS num FROM tempTable4;

最后再次成新的临时表,如下图:

5,HAVING num >= 2对上图所示临时表中的数据再次过滤,与WHERE语句不同的是HAVING 用在GROUP BY之后,WHERE是对FROM student从数据库表文件加载到内存中的原生数据过滤,而HAVING 是对SELECT 语句执行之后的临时表中的数据过滤,所以说column AS otherName ,otherName这样的字段在WHERE后不能使用,但在HAVING 后可以使用。但HAVING的后使用的字段只能是SELECT 后的字段,SELECT后没有的字段HAVING之后不能使用。HAVING num >= 2语句执行之后生成一张临时表,如下:

6,ORDER BY num DESC,`name` ASC对以上的临时表按照num,name进行排序。

7,LIMIT 0,2取排序后的前两个。

参考文章:https://blog.csdn.net/sinat_32176267/article/details/83280206

[转]MySQL查询语句执行过程详解的更多相关文章

  1. mysql中SQL执行过程详解与用于预处理语句的SQL语法

    mysql中SQL执行过程详解 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器段进行SQL解析.预处理,在优化器生成对应的 ...

  2. MySQL 语句执行过程详解

    MySQL 原理篇 MySQL 索引机制 MySQL 体系结构及存储引擎 MySQL 语句执行过程详解 MySQL 执行计划详解 MySQL InnoDB 缓冲池 MySQL InnoDB 事务 My ...

  3. MySQL查询语句执行过程及性能优化(JOIN/ORDER BY)-图

    http://blog.csdn.net/iefreer/article/details/12622097 MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY) 标签 ...

  4. MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY)

    在上一篇文章MySQL查询语句执行过程及性能优化-基本概念和EXPLAIN语句简介中介绍了EXPLAIN语句,并举了一个慢查询例子:

  5. Mysql查询语句执行过程

    Mysql查询语句执行过程   Mysql分为server层和存储引擎两部分,或许可以再加一层连接层   连接层(器) Mysql使用的是典型的C/S架构.连接器通过典型的TCP握手完成连接. 需要注 ...

  6. MySQL查询语句执行过程及性能优化-基本概念和EXPLAIN语句简介

    网站或服务的性能关键点很大程度在于数据库的设计(假设你选择了合适的语言开发框架)以及如何查询数据上. 我们知道MySQL的性能优化方法,一般有建立索引.规避复杂联合查询.设置冗余字段.建立中间表.查询 ...

  7. SQL语句执行过程详解

    一.SQL语句执行原理: 第一步:客户端把语句发给服务器端执行 当我们在客户端执行select语句时, 客户端会把这条SQL语句发送给服务器端,让服务器端的进程来处理这语句.也就是说,Oracle客户 ...

  8. Hadoop MapReduce执行过程详解(带hadoop例子)

    https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...

  9. ping命令执行过程详解

    [TOC] ping命令执行过程详解 机器A ping 机器B 同一网段 ping通知系统建立一个固定格式的ICMP请求数据包 ICMP协议打包这个数据包和机器B的IP地址转交给IP协议层(一组后台运 ...

随机推荐

  1. 【github】github的使用

    一.上传本地代码 1.在github上新建一个repository(命名为英文) 2.打开cmd,进入上传代码所在目录 3.输入如下命令 第一步:git init --建仓第二步:git add  * ...

  2. Linux基础篇之CentOS的网络配置(DHCP,静态)

    1.启动系统,使用用户名.密码登录系统:  2. 配置网卡(DHCP获取IP地址.静态手动配置IP地址): 网卡的默认信息  DHCP模式修改为(下图): 静态IP地址修改为(下图): 无论哪种配置, ...

  3. HTML5常用的语义化标签

    快速查询 article | aside | nav | section | header | footer 架构预览 nav 定义导航链接的部分 在页脚显示一个站点的导航链接,如首页.服务信息页面. ...

  4. win10家庭版设置移动热点出现“我们无法设置移动热点”

    寝室wifi卡到爆炸,  买了一个360随身WiFi,可是360随身WiFi烧坏了  ...然后我就一个星期没玩游戏了 今天本来想开电脑的wifi试一试,结果发现无法设置热点 纳闷了 百度一下,发现都 ...

  5. string::capacity string::size string::length string::max_size

    size_t capacity() const noexcept; #include <iostream>#include <string> using namespace s ...

  6. [NOI2008]假面舞会——数论+dfs找环

    原题戳这里 思路 分三种情况讨论: 1.有环 那显然是对于环长取个\(gcd\) 2.有类环 也就是这种情况 1→2→3→4→5→6→7,1→8→9→7 假设第一条链的长度为\(l_1\),第二条为\ ...

  7. mongodb命令---花样查询语句

    闲言少叙 查出价格低于200的商品信息----包含商品名称,货物编号,价格,添加信息等 db.goods.find( {}}, {,,,} ) 商品分类不为3的商品 db.goods.find( {} ...

  8. redis geo操作

    package club.newtech.qbike.trip.domain.service; import club.newtech.qbike.trip.domain.core.Status;im ...

  9. [React] Reduce Code Redundancy with Custom React Hooks

    In this lesson, we'll cover how to create a custom React hook for managing the state of any input. T ...

  10. php判断文件是否为txt文件

    可以使用pathinfo方法来通过后缀名进行判断文件类型. /** * 获取文件后缀(如果文件名为11.11,11不是后缀,会默认11为后缀) * $file string 文件路径或者文件名 */ ...