image.png

请求执行过程

客户端发起一次查询请求,MySQL服务器接收到请求之后,会先经过查询缓存,先判断之前是否经历过相似的查询,并且有记录相同的结果。

如果有,从缓存中读取数据,直接返回数据给客户端。

如果没有,请求交给解析器,解析器会进行语句的词法和语法的分析,生成解析树,之后交给预处理器,预处理器会检查解析树是否合法,同时会进行表列别名的校验,之后经过权限校验生成新的解析树,这个新的解析树其实是一条指令树,这个指令树会交给查询优化器去优化,MySQL的查询优化器会对指令树进行调优,调优后会生成执行计划,执行计划会交给执行引擎去调度,执行引擎在调度的时候会使用存储引擎提供的API进行数据的检索,存储引擎检索到数据之后返回给执行引擎,执行引擎拿到执行结果后进行返回给客户端。

注意:数据的检索是由存储引擎来实现的,执行引擎只负责数据查询的调度以及拿到结果之后的过滤、排序。

逻辑架构介绍

查询缓存

查询缓存会将之前有相同的查询且保存了记录的数据直接返回给客户端

  • 结构:哈希表,key由查询语句本身,查询的数据库和客户端协议的版本等生成

  • 作用:提升查询性能,对应程序透明

  • 副作用:写缓存和清缓存由性能损耗,尤其对写密集的应用
    image-0030b58c缓存命中率:Qcache_hits / (Qcache_hits + Com_select),但是能使用缓存的有效版本:4.1 ~ 5.7.20,5.7.20已deprecated,8.0开始移除此功能

    另外延伸一个点,mysql的缓存和java应用的一级缓存二级缓存不是同一个概念

解析器

解析器会对客户端提交的查询进行词法和语法的分析,然后会生成解析树。

  • 词法分析:语句分词,解析出关键字,函数名等token
  • 语法分析:基本语法规则校验,比如关键词

预处理器

预处理器会检查解析器的解析树是否合法,同时会进行查询内容表、列、别名的校验,之后经过权限校验生成新的解析树,这个新的解析树其实是一条指令树。

  • 校验表和列是否存在,字段别名是否由歧义,权限验证等

查询优化

MySQL的查询优化器会对指令树进行调优,调优后会生成执行计划,执行计划会交给执行引擎去调度。

  • 重排关联表顺序

    减少扫描行数,可通过STRAIGHT JOIN 关键字取消重排

  • 等价变换

    简化表达式,去除冗余判断等,比如(5=5 and a >5) ☞ a >5

  • 子查询优化

    子查询需要创建临时表,一般会转为表连接

  • 覆盖索引扫描

    直接访问索引就可以获取到所需要的数据,不需要通过索引取数据行

  • 提前终止

    已查到满足条件的数据(使用limit)或者检测到where条件不可能成立时

执行计划

  • EXPLAIN

    查看SQL执行计划,也是优化查询性能的利器
    用法:EXPLAIN + SQL 或EXPLAIN + SQL \G
    image-1851acec

  • SHOW WARNINGS

    显示最后一个执行的语句所产生的错误、警告和提示等信息
    在EXPLAIN之后,执行该语句可以看到重建后的查询语句
    image-1851acec

执行引擎

执行引擎在调度的时候会使用存储引擎提供的API进行数据的检索

并且MySQL对任何关联都执行嵌套循环关联操作(Nested-Loop Join)

select v.VideoID, v.Title, c.CityID  
from VideoBase v left outer join CityVideoIndex c  
on v.VideoID = c.VideoID where c.CityID is not null

image-20b0cd6d

如上方sql,执行引擎会把左外连接变成内连接再执行查询

select v.VideoID, v.Title, c.CityID  
from VideoBase v join CityVideoIndex c  
on v.VideoID = c.VideoID where c.CityID is not null

存储引擎

负责数据的存储和查询,以及提供一整套查询的工具,检索到数据后返回给执行引擎。

image-71bfd57c

回顾

image-9983bef1

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

越努力,越幸运!