MySQL—一条查询SQL语句的完整执行流程

这篇具有很好参考价值的文章主要介绍了MySQL—一条查询SQL语句的完整执行流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MySQL—一条查询SQL语句的完整执行流程

表结构和数据如下:

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

我们分析的sql语句如下:

select tb_id,tb_name,tb_address from tb_user where tb_id = 66;

大体来说,MySQL可以分为Server层和存储引擎层两部分:

Server层

  • 包括:连接器、查询缓存、分析器、优化器、执行器等

  • 涵盖MySQL的大多数核心服务功能

  • 所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现

    • 比如:存储过程、触发器、视图等
  • 存储引擎层:

    • 负责数据的存储和提取
    • 可插拔式存储引擎:InnoDB、MyISAM、Memory等
      • 最常用存储引擎是InhoDB
      • 从MySQL 5.5版本开始,默认存储引擎是lnnoDB

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

第一步:连接到数据库

首先会连接到这个数据库上,这时候接待我们的就是连接器。

mysql -uroot -p

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

连接完成后,如果没有后续的动作,这个连接就处于空闲状态。客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数wait_timeout控制的,默认值是8小时。

show processlist;

其中的 Command 列显示为“Sleep”的这一行,就表示现在系统里面有一个空闲连接。

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

第二步:查缓存

MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以key-value对的形式,被直接缓存在内存中。key是查询的语句hash之后的值,value是查询的结果。

  • 如果查询语句在缓存中,会被直接返回给客户端。

  • 如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。

如果查询命中缓存,MySQL不需要执行后面的复杂操作就可以直接返回结果,效率会很高!但是不建议使用MySQL的内置缓存功能。

查询缓存

查询缓存默认是关闭的状态。

# 查看是否开启缓存
show variables like 'query_cache_type';
# 查看缓存的命中次数:
show status like 'qcache_hits';

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

开启缓存

/etc/my.cnf文件中修改“query_cache_type”参数

值为`0或OFF`会禁止使用缓存。
值为`1或ON`将启用缓存,但以`SELECT SQL_NO_CACHE`开头的语句除外。
值为`2或DEMAND`时,只缓存以`SELECT SQL_CACHE`开头的语句。

清空查询缓存

可以使用下面三个SQL来清理查询缓存:

# 清理查询缓存内存碎片。
FLUSH QUERY CACHE; 
# 从查询缓存中移出所有查询。
RESET QUERY CACHE;
# 关闭所有打开的表,同时该操作将会清空查询缓存中的内容。
FLUSH TABLES; 

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

不建议使用MySQL的查询缓存

因为查询缓存往往弊大于利

  • 成本高:查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了。

  • 命中率不高:对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。

  • 功能并不如专业的缓存工具更好:redis、memcache、ehcache…
    MySQL提供了按需使用的方式,我们可以将参数query_cache_type设置成DEMAND,这样对于默认的SQL语句都不使用查询缓存。而对于你确定要使用查询缓存的语句,可以用SQL_CACHE显式指定,像下面这个语句一样:

    select sql_cache * from tb_user where tb_id = 16;
    

MySQL 8.0 版本直接将查询缓存的整块功能删掉了。

第三步:分析SQL语句

如果查询缓存没有命中,接下来就需要进入正式的查询阶段了。客户端程序发送过来的请求,实际上只是一个字符串而已,所以MySQL服务器程序首先需要对这个字符串做分析,判断请求的语法是否正确,然后从字符串中将要查询的表、列和各种查询条件都提取出来,本质上是对一个SQL语句编译的过程,涉及词法解析、语法分析、预处理器等。

  • 词法分析:词法分析就是把一个完整的SQL语句分割成一个个的字符串;
  • 语法分析:语法分析器根据词法分析的结果做语法检查,判断你输入的SQL语句是否满足MySQL语法;
  • 预处理器:预处理器则会进一步去检查解析树是否合法,比如表名是否存在,语句中表的列是否存在等等,在这一步MySQL会检验用户是否有表的操作权限。

词法分析

比如我们前文所提到的sql语句,分割前为:

select tb_id,tb_name,tb_address from tb_user where tb_id = 66;

分割后为

select,
tb_id,
tb_name,
tb_address,
from,
tb_user,
where,
tb_id,
=,
66
;

MySQL同时需要识别出这个SQL语句的字符串分别是什么,代表什么。

  • 把select关键字识别出来,是查询语句;
  • 把tb_user识别出来是表名tb_user

语法分析

如果语法正确就会根据MySQL语法规则与SQL语句生成一个数据结构——解析树

如果我们把from写成form

会报出如下错误:

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

我们前面的SQL语句,生成解析树如下:

select tb_id,tb_name,tb_address from tb_user where tb_id = 66;

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

预处理器

预处理器会进一步去检查解析树是否合法,比如表名是否存在,语句中表的列是否存在等等,在这一步MySQL会检验用户是否有表的操作权限。

预处理之后会得到一个新的解析树,然后调用对应执行模块。

第四步:优化SQL语句

优化器顾名思义就是对查询进行优化。作用是根据解析树生成不同的执行计划,然后选择最优的执行计划。

MySQL里面使用的是基于成本模型的优化器,哪种执行计划Explain执行时成本最小就用哪种。而且它是io_cost和cpu_cost的开销总和,它通常也是我们评价一个查询的执行效率的一个常用指标。

show status like 'Last_query_cost';

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

查看上次查询成本开销,默认值是0

优化器可以做的优化有:

  • 当有多个索引可用的时候,决定使用哪个索引;
  • 在一个语句有多表关联(join)的时候,决定各个表的连接顺序,以哪个表为基准表。

优化器最多是辅助,作用很有限,我们的SQL语句不能依赖于MySQL的优化器去调优!

第五步:执行SQL语句

判断执行权限

开始执行的时候,要先判断一下对这表tb_user有没有执行查询的权限,如果没有权限,就会返回无权限的错误。

比如:我们新建一个用户hello_user,只有库sjdwz_testtab_test的查询权限,没有表tb_user的查询权限。

CREATE USER `hello_user`@`localhost` IDENTIFIED BY '7654321@Hello';
GRANT Select ON TABLE `sjdwz_test`.`tab_test` TO `hello_user`@`localhost`;

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

使用这个用户hello_user连接mysql,

mysql -uhello_user -p

执行下面的查询语句,就会返回没有权限的错误

select tb_id,tb_name,tb_address from tb_user where tb_id = 66;

MySQL—一条查询SQL语句的完整执行流程,MySQL,mysql,数据库

调用存储引擎接口查询

如果有权限,就使用指定的存储引擎打开表开始查询。执行器会根据表的引擎定义,去使用这个引擎提供的查询接口提取数据。文章来源地址https://www.toymoban.com/news/detail-861394.html

  • tb_id是主键执行流程:
    • 调用InnoDB引擎接口,从主键索引中检索c_id=14的记录。
    • 主键索引等值查询只会查询出一条记录,直接将该记录返回客户端。
    • 至此,这个语句就执行完成了。
  • tb_id不是主键执行流程:全表扫描
    • 调用InnoDB引擎接口取这个表的第一行,判断tb_id 值是不是66,如果不是则跳过,如果是则将这行缓存在结果集中;
    • 调用引擎接口取”下一行",重复相同的判断逻辑,直到取到这个表的最后一行。
    • 执行器将上述遍历过程中所有满足条件的行组成的结果集返回给客户端。
    • 至此,这个语句就执行完成了。

到了这里,关于MySQL—一条查询SQL语句的完整执行流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL执行流程_执行一条select语句,期间发生了什么

    MySQL执行流程 server层负责建立连接、分析和执行SQL 包括连接器、查询缓存、解析器、预处理器、优化器、执行器等,所有内置函数和所有跨存储引擎的功能在该层实现 存储引擎层负责数据的存储和提取 索引数据结构就是由存储引擎层实现,不同的存储引擎支持的索引类型也

    2024年02月04日
    浏览(18)
  • 如何进行MySQL源码调试(一条select语句的执行流程)

    一、背景 MySQL是当今世上最受欢迎的使用最广泛的开源数据库,它的繁荣离不开它的开源特性。放在过去商业数据库的时代,大家都没有机会接触到数据库的源代码,但在如今开源数据库的时代,越来越多的人开始研究数据库的源码,并给社区贡献代码,MySQL官方每次发布新

    2024年02月03日
    浏览(17)
  • MySQL面试题:一条SQL语句在MySQL中执行过程全解析

    介绍一下下图涉及的一些组件的基本作用帮助大家理解这幅图。 连接/线程处理(连接器): 身份认证和权限相关(如连接处理、授权认证、安全等等)。 查询缓存: 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除)。 解析器: 没有命中缓存的话,SQL 语句就会经过解析

    2024年02月03日
    浏览(14)
  • myql进阶-一条查询sql在mysql的执行过程

    目录 1. 流程图 2. 各个过程 2.1 连接器 2.2 分析器 2.3 优化器 2.4 执行器 2.5 注意点 假设我们执行一条sql语句如下: 首先我们会和mysql建立连接,此时就会执行到连接器。 连接器的职责是负责和客户端建立连接、获取权限、维持和管理连接。 我们执行sql之前首先要和数据库建立

    2024年01月21日
    浏览(25)
  • 从Mysql架构看一条查询sql的执行过程

    我们的程序或者工具要操作数据库,第一步要做什么事情? 跟数据库建立连接。 首先,MySQL必须要运行一个服务,监听默认的3306端口。在我们开发系统跟第三方对接的时候,必须要弄清楚的有两件事。 第一个就是通信协议,比如我们是用HTTP还是WebService还是TCP? 第二个是消

    2024年02月08日
    浏览(16)
  • 01 | 一条 SQL 查询语句是如何执行的?

    以下内容出自 《MySQL 实战 45 讲》 一条 SQL 查询语句是如何执行的? 下面是 MySQL 的基本架构示意图,从中可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程。 大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。 Server 层包括连接器、查询缓存、分析器、优化器

    2024年02月10日
    浏览(14)
  • 01 | 基础架构:一条SQL查询语句是如何执行的?

    画出 MySQL 的基本架构图 Server 层和存储引擎层各自有哪些组件? Server 层 连接器 查询缓存 分析器 优化器 执行器 所有内置函数(日期、时间、数学和加密函数等) 所有跨存储引擎的功能(存储过程、触发器、视图等) 存储引擎层 负责数据的存储和读取 连接器的作用? 连接

    2024年02月08日
    浏览(19)
  • MySQL中,SQL 查询总是先执行SELECT语句吗?

    在使用 MySQL 进行查询时,我们通常会使用 SELECT 语句,但是 SELECT 语句是否总是最先被执行呢?这是一个非常有趣的问题,本文将对此进行探讨。 在 MySQL 中,SQL 查询通常包括以下几个步骤: 语法解析 :MySQL 会对 SQL 查询语句进行语法解析,检查语句是否符合 SQL 语法规范。

    2023年04月09日
    浏览(13)
  • MySQL一条语句递归查询所有子集数据

    MySQL中,现有一组数据,数据包含字段主键:id,父类ID:pid,id与pid是继承关系,根据某个id查询其下级关联的所有记录; 1、利用递归查询语法。递归查询是在 MySQL 8.0 版本引入的新特性,如果您的 MySQL 版本低于 8.0,则无法使用递归查询语法。 在上面的语句中,使用了 Com

    2024年02月11日
    浏览(14)
  • 一条SQL在MySQL中是如何执行的

    MySQL的内部组件结构 连接数据库做了什么? 建立链接的时候需要将host,user,pwd,在user表中校验用户(用户名和密码)是否正确。每个链接链接到服务器端之后会给链接开辟一个专属的空间。这个空间存储了很多这个链接需要使用的操作。并且会把这个用户的权限都放到这个空间

    2023年04月09日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包