Mysql查询语句执⾏过程及运⾏原理
Mysql查询语句执⾏原理
数据库查询语句如何执⾏?
1. DML语句⾸先进⾏语法分析,对使⽤sql表⽰的查询进⾏语法分析,⽣成查询语法分析树。
2. 语义检查:检查sql中所涉及的对象以及是否在数据库中存在,⽤户是否具有操作权限等
3. 视图转换:将语法分析树转换成关系代数表达式,称为逻辑查询计划;
4. 查询优化:在选择逻辑查询计划时,会有多个不同的表达式,选择最佳的逻辑查询计划;
5. 代码⽣成:必须将逻辑查询计划转换成物理查询计划,物理查询计划不仅能指明要执⾏的操作,也给出了这些操作的执⾏顺序,每步
所⽤的算法,存储数据的⽅式以及从⼀个操作传递给另⼀个操作的⽅式。
6. 将DML转换成⼀串可执⾏的存取操作的过程称为束缚过程,
Mysql查询语句执⾏过程
这⾥简单介绍⼀下mysql数据库,mysql数据库是⼀款关系型数据库,所谓关系型数据库就是以⼆维表的形式存储数据,使⽤⾏和列⽅便我们对数据的增删改查。
  这篇博客,我们以mysql数据库为例,对⼀条sql语句的执⾏流程进⾏分析。(本篇博客不涉及到表连接)
  ⾸先,创建⼀张student表,字段有⾃增主键id,学⽣姓名name,学科subject,成绩grade
  建表语句:
1DROP TABLE IF EXISTS student;
2CREATE TABLE `student` (
3  `id` int(5) NOT NULL AUTO_INCREMENT,
手机版易语言编程软件4  `name` varchar(10) DEFAULT NULL,
5  `subject` varchar(10) DEFAULT NULL,
6  `grade` double(4,1) DEFAULT NULL,
7  PRIMARY KEY (`id`)
8) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;
  初始化数据:
1INSERT INTO student(`name`,`subject`,grade)VALUES('aom','语⽂',88);
2INSERT INTO student(`name`,`subject`,grade)VALUES('aom','数学',99);
3INSERT INTO student(`name`,`subject`,grade)VALUES('aom','外语',55);
4
5INSERT INTO student(`name`,`subject`,grade)VALUES('jack','语⽂',67);
6INSERT INTO student(`name`,`subject`,grade)VALUES('jack','数学',44);
default路由器7INSERT INTO student(`name`,`subject`,grade)VALUES('jack','外语',55);
8
java入门图解
9INSERT INTO student(`name`,`subject`,grade)VALUES('susan','语⽂',56);
10INSERT INTO student(`name`,`subject`,grade)VALUES('susan','数学',35);
empty的反义词11INSERT INTO student(`name`,`subject`,grade)VALUES('susan','外语',77);
12mysql语句多表查询
13INSERT INTO student(`name`,`subject`,grade)VALUES('alice','语⽂',88);
14INSERT INTO student(`name`,`subject`,grade)VALUES('alice','数学',77);
15INSERT INTO student(`name`,`subject`,grade)VALUES('alice','外语',100);
16
17INSERT INTO student(`name`,`subject`,grade)VALUES('rajo','语⽂',33);
18INSERT INTO student(`name`,`subject`,grade)VALUES('rajo','数学',55);
19INSERT 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 执⾏结果:
  图(1.1)
以上这条sql语句基本上概括了单表查询中所有要注意的点,那么我们就以这条sql为例来分析⼀下⼀条语句的执⾏流程。
1,⼀条查询的sql语句先执⾏的是 FROM student 负责把数据库的表⽂件加载到内存中去,如图1.0中所⽰。(mysql数据库在计算机上
也是⼀个进程,cpu会给该进程分配⼀块内存空间,在计算机‘服务’中可以看到,该进程的状态)
  图(1.2)
2,WHERE grade < 60,会把(图1.0)所⽰表中的数据进⾏过滤,取出符合条件的记录⾏,⽣成⼀张临时表,如下图所⽰。
  图(1.3)3,GROUP BY `name`会把图(1.3)的临时表切分成若⼲临时表,分为四个分组,我们⽤下图来表⽰内存中这个切分的过程。
        图(1.4)              图(1.5)         图(1.6)        图(1.7)
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分别对应图(1.4)、图(1.5)、图(1.6),图(1.7)下⾯写四条"伪SQL"来说明这个查询过程。
最后再次成新的临时表,如下图:diversity and distribution影响因子
  图(1.8)
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语句执⾏之后⽣成⼀张临时表,如下:   图(1.9)
6,ORDER BY num DESC,`name` ASC对以上的临时表按照num,name进⾏排序。
1
SELECT `name`,COUNT(`name`) AS num FROM tempTable1;2
SELECT `name`,COUNT(`name`) AS num FROM tempTable2;3SELECT `name`,COUNT(`name`) AS num FROM tempTable3;4SELECT `name`,COUNT(`name`) AS num FROM tempTable4;
7,LIMIT 0,2取排序后的前两个。
转存失败
以上就是⼀条sql的执⾏过程,同时我们在书写查询sql的时候应当遵守以下顺序。SELECT XXX FROM XXX WHERE XXX GROUP BY XXX HAVING XXX ORDER BY XXX LIMIT XXX;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。