关于mysql:MySQL-查询SQL执行流程

9次阅读

共计 2335 个字符,预计需要花费 6 分钟才能阅读完成。

简述

大体来说,MySQL 能够分为 Server 层和存储引擎层两局部。

Server 层包含连接器、查问缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数外围服务性能,以及所有的内置函数(如日期、工夫函数等),所有跨存储引擎的性能都在这一层实现,比方存储过程、触发器、视图等。而存储引擎层负责数据的存储和提取。

其架构模式是插件式的,反对 InnoDB、MyISAM、Memory 等多个存储引擎。最罕用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。也就是说,你执行 create table 建表的时候,如果不指定引擎类型,默认应用的就是 InnoDB。

也就是说,你执行 create table 建表的时候,如果不指定引擎类型,默认应用的就是 InnoDB。不过,你也能够通过指定存储引擎的类型来抉择别的引擎,比方在 create table 语句中应用 engine=myisam, 来指定引擎创立表。不同存储引擎的表数据存取形式不同,反对的性能也不同。

连接器

第一步,连贯到这个数据库上,这时候接待你的就是连接器。连接器负责跟客户端建设连贯、获取权限、维持和治理连贯。一般来说命令的写法

mysql -h $ip -P $port -u $user -p

输出完命令后,须要输出完明码后即可连贯胜利。-p 前面是明码,一般来说不倡议间接在命令下面输出明码,这样可能导致明码透露。

连贯中的 mysql 是客户端工具,用来和服务器建设连贯。在实现 TCP 握手后,服务器的连接器开始认证你的身份。包含用户、明码、权限、等等:

  • 如果用户名或明码谬误,会报出 ”Access denied for user” 的谬误,而后完结执行
  • 如果认证都通过,连接器会在权限表里查问该账号的所有权限。之后的权限判断都基于此权限判断

也就是说,一旦连贯胜利后,在断开连接的状况下,即便批改了权限,权限也不会产生变动。除非断开从新连贯。所以通常,不倡议长连贯。

查问缓存

连贯建设实现后,你就能够执行 select 语句了。执行逻辑就会来到第二步:查问缓存。

MySQL 拿到一个查问申请后,会先到查问缓存看看,之前是不是执行过这条语句。之前执行过的语句及其后果可能会以 k-v 对的模式,被间接缓存在内存中。k 是查问的语句,v 是查问的后果。如果你的查问可能间接在这个缓存中找到 k,那么这个 v 就会被间接返回给客户端。

如果语句不在查问缓存中,就会持续前面的执行阶段。执行实现后,执行后果会被存入查问缓存中。你能够看到,如果查问命中缓存,MySQL 不须要执行前面的简单操作,就能够间接返回后果,这个效率会很高。

然而大多数状况下不倡议应用查问缓存。因为查问缓存往往弊大于利。

查问缓存的生效十分频繁,只有有对一个表的更新,这个表上所有的查问缓存都会被清空。因而很可能你吃力地把后果存起来,还没应用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查问缓存的命中率会非常低。除非你的业务就是有一张动态表,很长时间才会更新一次。比方,一个系统配置表,那这张表上的查问才适宜应用查问缓存。

然而留神,改性能在 MySQL 在 8.0 版本之后删除了

分析器

首先,MySQL 须要晓得你要做什么,因而须要对 sql 语句做解析。

分析器会先做词法剖析,明确你的 sql 语句具体是做什么。

比方上面的 SQL
mysql> elect * from t where ID=1;
如:MySQL 从你输出的 ”select” 这个关键字辨认进去,这是一个查问语句。

它也要把字符串“T”辨认成“表名 T”,把字符串“ID”辨认成“列 ID”。
做完了这些辨认当前,就要做“语法分析”。依据词法剖析的后果,语法分析器会依据语法规定,判断你输出的这个 SQL 语句是否满足 MySQL 语法。

如果你的语句不对,就会收到“You have an error in your SQL syntax”的谬误揭示,比方上面这个语句 select 少打了结尾的字母“s”。
个别语法错误会提醒第一个呈现谬误的地位,所以你要关注的是紧接“use near”的内容。

优化器

通过了分析器,MySQL 就晓得你要做什么了。在开始执行之前,还要先通过优化器的解决。

优化器是在表外面有多个索引的时候,决定应用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连贯程序。比方你执行上面这样的语句,这个语句是执行两个表的 join:
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;

  • 既能够先从表 t1 外面取出 c=10 的记录的 ID 值,再依据 ID 值关联到表 t2,再判断 t2 外面 d 的值是否等于 20。
  • 也能够先从表 t2 外面取出 d=20 的记录的 ID 值,再依据 ID 值关联到 t1,再判断 t1 外面 c 的值是否等于 10。
    这两种执行办法的逻辑后果是一样的,然而执行的效率会有不同,而优化器的作用就是决定抉择应用哪一个计划。

优化器阶段实现后,这个语句的执行计划就确定下来了,而后进入执行器阶段。

执行器

MySQL 通过分析器晓得了你要做什么,通过优化器晓得了该怎么做,于是就进入了执行器阶段,开始执行语句。

开始执行的时候,要先判断一下你对这个表 T 有没有执行查问的权限,如果没有,就会返回没有权限的谬误。

如果有权限,就关上表继续执行。

如:
select * from T where ID=10;

如果没有索引的执行流程

  1. 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在后果集中。
  2. 调用引擎接口取“下一行”,反复雷同的判断逻辑,直到取到这个表的最初一行。
  3. 执行器将上述遍历过程中所有满足条件的行组成的记录集作为后果集返回给客户端。至此,这个语句就执行实现了。

至此,执行实现。
如果有索引,执行逻辑也差不多。~~~~

正文完
 0