0

0

MySQL学习之聊聊查询语句执行流程

青灯夜游

青灯夜游

发布时间:2023-01-11 20:38:55

|

1583人浏览过

|

来源于掘金社区

转载

如果想深入地学习 mysql ,那么应该从宏观的架构上面着手,这一篇我们学习 mysql 查询语句执行的流程,希望对大家有所帮助!

MySQL学习之聊聊查询语句执行流程

本篇文章 MySQL 版本为 8.0.18

架构图

解析器

解析器的作用是对客户端传来的 SQL 语句进行以下工作:

  • 语法解析:检查 SQL 语句的语法,括号、引号是否闭合等
  • 词法解析:把 SQL 语句中的关键词、表名、字段名拆分成一个个节点,最终得到一颗解析树

预处理器

解析器主要是检查语法词法方面,但是如果语法词法都正确,但是表、字段是不存在的,那么这段 SQL 语句也是无法正确执行的。

所以预处理器的作用是:语义解析,判断解析树的语义是否正确,表、字段这些是否存在,预处理后会得到一颗新的解析树。

查询优化器

查询优化器结构

在 MySQL 中一条 SQL 语句的执行方式有多种,虽然最终都会得到相同的结果,但是存在开销上的差异,具体选择哪一种执行方式是由查询优化器来决定的。比如说:

  • 表中有多个索引可以选择,具体选择哪一个索引
  • 当我们对多张表进行关联查询时,以哪一张表的数据为基准表

查询优化器是基于开销(cost)的优化器,它的工作原理是根据解析树生成的多种执行计划,会评估各种执行方式所需的开销(cost),最终会得到一个开销最小的执行计划作为最终方案

但是这个开销最小的执行方式不一定是最优的执行方式,比如本该使用索引,却进行了全表扫描等。虽然查询优化器中有《优化》两个字,但是这个优化并不是万能的,很多时候更加需要考虑 SQL 语句书写得是否合理。

逻辑查询优化

逻辑查询优化主要负责进行一些关系代数对 SQL 语句进行优化,从而使 SQL 语句执行效率更高

逻辑查询优化我们可以使用几个案例来简单理解

  • 子查询合并

    合并前

    SELECT * FROM t1 WHERE a1<10 AND (
      EXISTS(SELECT a2 FROM t2 WHERE t2.a2<5 AND t2.b2=1) OR
      EXISTS(SELECT a2 FROM t2 WHERE t2.a2<5 AND t2.b2=2)
    );

    合并后

    SELECT * FROM t1 WHERE a1<10 AND (
      EXISTS(SELECT a2 FROM t2 WHERE t2.a2<5 AND (t2.b2=1 OR t2.b2=2)
    );

    把多个子查询通过合并查询条件而合并查询,把多次连接操作减少为单次表扫描和单次连接

  • 等价谓词重写

    像我们熟悉的 like 模糊查询,% 写在条件后面才会进行索引范围查询,其实这是查询优化器的功劳

    假设使用的条件都是有建立索引的,重写前

    SELECT * FROM USERINFO WHERE name LIKE 'Abc%';

    重写后

    SELECT * FROM USERINFO WHERE name >= 'Abc' AND name < 'Abd';

    这就是为什么能进行索引范围查询的答案

  • 条件简化

    条件简化也是利用一些等式、代数关系来实现简化

    ChartCube
    ChartCube

    图标魔方 - 在线图表制作工具

    下载
    • 去除表达式中的冗余括号,减少语法分析时产生的AND和OR 树的层 次,比如 ((a AND b) AND (c AND d)) 简化为 a AND b AND c AND d
    • 常量传递,比如 col1 = col2 AND col2 = 3 简化为 col1 = 3 AND col2 = 3
    • 表达式计算,对于一些可直接求解的表达式会转换为最终的计算结果,比如 col1 = 1+2 简化为 col1 = 3

物理查询优化

物理查询优化主要做的工作是根据 SQL 语句分别对多种执行计划进行开销的评估

物理查询优化主要解决以下几个问题:

  • 单表扫描中采用哪种方式是开销最小的(扫描索引+回表 or 全表扫描)

  • 存在表连接的时候使用哪种连接方式是开销最小的

简单了解一下代价评估,代价评估是基于 CPU 代价和 IO 代价两个维度的

扫描方式 代价评估公式
顺序扫描 N_page * a_page_IO_time + N_tuple * a_tuple_CPU_time
索引扫描 C_index + N_page_index * a_page_IO_time

上述参数说明如下:

  • a_page_IO_time, 一个数据页加载的IO耗时
  • N_page,数据页数量
  • N_tuple,元组数(元组理解为一行数据)
  • a_tuple_CPU_time,一个元组从数据页中解析的CPU耗时
  • C_index,索引的IO耗时
  • N_page_index,索引页数量

关于索引成本计算可以参考这篇文章:MySQL查询为什么选择使用这个索引?——基于MySQL 8.0.22索引成本计算

执行计划

执行计划是查询优化器的产物,最终会交给存储引擎进行执行。执行计划可以帮助我们得知 MySQL 会怎么执行这条 SQL 语句。

使用 explain 关键字查看 SQL 语句的执行计划,可以得到以下信息:

  • id:嵌套查询中查询的执行顺序
  • possible_keys:本次查询可能用到的索引
  • Key:实际用到的索引
  • rows:得到结果大概要检索多少行数据
  • select_type多表之间的连接类型
  • extra:额外的信息,是否有索引覆盖、索引下推等

存储引擎

MySQL 服务端规定了数据如何存储、如何提取、如何更新的规范,这个规范由存储引擎来实现,不同的存储引擎的实现方式不同,所以不同的存储引擎会呈现其独特的功能和特点。其中最常用的存储引擎是 InnoDB 和 MyISAM

简单说说这两款存储引擎的特点

InnoDB:

  • 支持外键、事务,保证了数据的完整性和一致性
  • 支持更细的锁粒度,对锁的控制更好,读写效率更高

MyISAM

  • 不支持事务,只支持行锁,适合数据只读的场景

存储引擎方面暂时先不展开,会在其他文章继续穿插他们的对比,以及会详细分析 InnoDB 更新数据的流程

总结

从前,只知道在客户端软件上写下 SQL 语句,点击执行,拿到数据

到现在终于了解到一条查询语句传入 MySQL 服务端后需要经历这一系列的操作

  • 解析器根据这条 SQL 语句的语法、词法进行检查,如果没有错误的话会按关键词拆分成一个个节点,最终形成一棵解析树

  • 预处理器会检查 SQL 语句的语义,检查 SQL 语句是否有歧义、字段等是否存在,形成一棵新的解析树

  • 查询优化器拿到这个解析树生成的各种执行计划,经过逻辑查询优化、物理查询优化后得到一个开销最小的执行计划

  • 执行引擎拿到这份执行计划调用存储引擎的接口

  • 存储引擎根据执行计划进行数据查询,查询会查询调用操作系统中文件系统的一些接口,完成数据查询,最后返回给客户端

【相关推荐:mysql视频教程

相关专题

更多
ip地址修改教程大全
ip地址修改教程大全

本专题整合了ip地址修改教程大全,阅读下面的文章自行寻找合适的解决教程。

86

2025.12.26

压缩文件加密教程汇总
压缩文件加密教程汇总

本专题整合了压缩文件加密教程,阅读专题下面的文章了解更多详细教程。

50

2025.12.26

wifi无ip分配
wifi无ip分配

本专题整合了wifi无ip分配相关教程,阅读专题下面的文章了解更多详细教程。

100

2025.12.26

漫蛙漫画入口网址
漫蛙漫画入口网址

本专题整合了漫蛙入口网址大全,阅读下面的文章领取更多入口。

293

2025.12.26

b站看视频入口合集
b站看视频入口合集

本专题整合了b站哔哩哔哩相关入口合集,阅读下面的文章查看更多入口。

589

2025.12.26

俄罗斯搜索引擎yandex入口汇总
俄罗斯搜索引擎yandex入口汇总

本专题整合了俄罗斯搜索引擎yandex相关入口合集,阅读下面的文章查看更多入口。

725

2025.12.26

虚拟号码教程汇总
虚拟号码教程汇总

本专题整合了虚拟号码接收验证码相关教程,阅读下面的文章了解更多详细操作。

63

2025.12.25

错误代码dns_probe_possible
错误代码dns_probe_possible

本专题整合了电脑无法打开网页显示错误代码dns_probe_possible解决方法,阅读专题下面的文章了解更多处理方案。

30

2025.12.25

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

94

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 7.5万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.1万人学习

Vue 教程
Vue 教程

共42课时 | 5.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号