深入学习MySQL,从概览MySQL逻辑架构开始。

首先来看一下MySQL的逻辑架构图:

MySQL逻辑架构大概可以分为三层:

  • 客户端:最上层的服务并不是MySQL所独有的,大多数基于网络的客户端/服务器的工具或者服务都有类似的架构。比如连接处理、授权认证、安全等等。
  • Server层:大多数MySQL的核心服务功能都在这一层,包括查询解析、分析、优化、缓存以及所有的内置函数(例如,日期、时间、数学和加密函数),所有跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。
  • 存储引擎层:第三层包含了存储引擎。存储引擎负责MySQL中数据的存储和提取。Server层通过API与存储引擎进行通信。这些接口屏蔽了不同存储引擎之间的差异,使得这些差异对上层的查询过程透明。

值得一提的是在MySQL8.0中取消了查询缓存,大概的理由是查询缓存存在严重的可伸缩性问题,并且很容易成为严重的瓶颈缓存,将缓存移动到客户端能收获更好的性能。

通过一条查询语句的执行过程,来了解一些关键的部件:

mysql> select * from T where ID=10;

1、连接器

首先,需要连接数据库。

当客户端(应用)连接到MySQL服务器时,服务器需要对其进行认证。认证基于用户名、原始主机信息和密码。

连接命令:

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

除了基本认证之外,连接器还会进行一些线程的处理。

每个客户端连接都会在服务器进程中拥有一个线程,这个连接的查询只会在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行。服务器会负责缓存线程,因此不需要为每一个新建的连接创建或者销毁线程。

2、查询缓存

对于SELECT语句,在解析查询之前,服务器会先检查查询缓存(Query Cache),如果能够在其中找到对应的查询,服务器就不必再执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集。

但不推荐使用查询缓存,为什么呢?因为查询缓存往往弊大于利。

查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。

好在MySQL也提供了这种“按需使用”的方式。可以将参数query_cache_type设置成DEMAND,这样对于默认的SQL语句都不使用查询缓存。而对于确定要使用查询缓存的语句,可以用SQL_CACHE显式指定,如下:

mysql> select SQL_CACHE * from T where ID=10;

上面也提到了MySQL8.0彻底废弃了查询缓存的功能。

3、解析器

如果缓存没有命中的话,MySQL会对查询语句进行解析。简单说解析的作用将我们人能看懂的SQL解析成MySQ能识别的语言。

解析器先会做“词法解析”。输入的是由多个字符串和空格组成的一条SQL语句,MySQL需要识别出里面的字符串分别是什么,代表什么。

MySQL从输入的"select"这个关键字识别出来,这是一个查询语句。它也要把字符串“T”识别成“表名T”,把字符串“ID”识别成“列ID”。

做完了这些识别以后,就要做“语法解析”。根据词法解析的结果,语法解析器会根据语法规则,判断输入的这个SQL语句是否满足MySQL语法。

4、优化器

经过了解析器器,MySQL知道我们要干什么。

接下来并不是直接执行,而是会在优化器这一层进行优化,优化器是个非常复杂的部件,它会帮我去使用他自己认为的最好的方式去优化这条 SQL 语句,并生成一条条的执行计划。

例如在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(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。

这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。

优化器阶段完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段。如果你还有一些疑问,比如优化器是怎么选择索引的,有没有可能选择错等等,没关系,我会在后面的文章中单独展开说明优化器的内容。

5、执行器

MySQL通过解析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,执行器会根据一系列的执行计划去调用存储引擎的接口去完成SQL的执行。

开始执行的时候,要先判断一下你对这个表T有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示(在工程实现上,如果命中查询缓存,会在查询缓存放回结果的时候,做权限验证。查询也会在优化器之前调用precheck验证权限)。

mysql> select * from T where ID=10;

ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'

如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。

比如我们这个例子中的表T中,ID字段没有索引,那么执行器的执行流程是这样的:

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

至此,这个语句就执行完成了。

对于有索引的表,执行的逻辑也差不多。第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中已经定义好的。


参考:

【1】:《高性能MySQL》

【2】:极客时间 《MySQL实战45讲》

【3】:《MySQL技术内幕 InnoDB存储引擎》

【4】:MySQL 8.0: Retiring Support for the Query Cache

【5】:头条二面: 详解一条 SQL 的执行过程

MySQL提升笔记(1):MySQL逻辑架构的更多相关文章

  1. MySQL基础篇(05):逻辑架构图解和InnoDB存储引擎详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.MySQL逻辑架构 1.逻辑架构图 基于下面的逻辑架构图,可以大致熟悉MySQL各个架构组件之间的协同工作关系. 很经典的C/S架构风格, ...

  2. MySQL提升笔记(3)日志文件详解

    在MySQL数据库和InnoDB存储引擎中,有很多种文件,如:参数文件.日志文件.socket文件.pid文件.MySQL表结构文件.存储引擎文件. 本节重点关注日志文件,MySQL的复制.事务等重要 ...

  3. 吴裕雄--天生自然MySQL学习笔记:MySQL 安装

    所有平台的 MySQL 下载地址为: MySQL 下载:https://dev.mysql.com/downloads/mysql/ 注意:安装过程我们需要通过开启管理员权限来安装,否则会由于权限不足 ...

  4. 吴裕雄--天生自然MySQL学习笔记:MySQL 运算符

    要介绍 MySQL 的运算符及运算符的优先级. MySQL 主要有以下几种运算符: 算术运算符 比较运算符 逻辑运算符 位运算符 算术运算符 MySQL 支持的算术运算符包括: 在除法运算和模运算中, ...

  5. 吴裕雄--天生自然MySQL学习笔记:MySQL 导入数据

    1.mysql 命令导入 使用 mysql 命令导入语法格式为: mysql -u用户名 -p密码 < 要导入的数据库数据(runoob.sql) 实例: # mysql -uroot -p12 ...

  6. 吴裕雄--天生自然MySQL学习笔记:MySQL 处理重复数据

    有些 MySQL 数据表中可能存在重复的记录,有些情况允许重复数据的存在,但有时候我们也需要删除这些重复的数据. 防止表中出现重复数据 可以在 MySQL 数据表中设置指定的字段为 PRIMARY K ...

  7. 吴裕雄--天生自然MySQL学习笔记:MySQL 临时表

    MySQL 临时表在我们需要保存一些临时数据时是非常有用的.临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间. MySQL临时表只在当前连接可见,如果使用PHP脚本来创建My ...

  8. 吴裕雄--天生自然MySQL学习笔记:MySQL 事务

    MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成 ...

  9. 吴裕雄--天生自然MySQL学习笔记:MySQL GROUP BY 语句

    GROUP BY 语句根据一个或多个列对结果集进行分组. 在分组的列上我们可以使用 COUNT, SUM, AVG,等函数. GROUP BY 语法 SELECT column_name, funct ...

随机推荐

  1. privacy policy 隐私政策

    privacy policy 隐私政策 privacy agreement css layout & ssr page flex & center & fonts demo h ...

  2. vue mixin执行覆盖

    https://cn.vuejs.org/v2/guide/mixins.html 完整代码 vue-option-overwrite-strategies vue 自带的mixin如果钩子函数重复会 ...

  3. html 布局,上下各100px,中间自适应

    flex <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  4. NGK公链生态所如何保障用户的数字资产隐私安全?

    距离NGK生态所正式上线已经没剩下几天时间了,NGK全网算力总量正在持续猛增,NGK日活账户也在大幅度增多.可以看出,币圈的生态建设者们是十分看好NGK生态所的.那么,有这么多的生态建设者涌入NGK生 ...

  5. NGK全球启动大会圆满召开,一起预见区块链的美好未来!

    NGK Global全球启动大会在高新技术产业区硅谷于美国当地时间11月25日圆满召开!这次会议邀请了星盟高管.NGK全球各大市场领导人.NGK生态产业代表等上百位嘉宾出席,此次会议持续了一个多小时, ...

  6. uniapp 滑动切换

    说明:本案例的样式基于colorui组件库 感兴趣的小伙伴可以看下教程 colorui组件库开发文档或者csdn的文档,顺便再分享下 colorui的群资源 最近项目中需要用到滑动切换的效果,自己懒得 ...

  7. spring扩展点整理

    本文转载自spring扩展点整理 背景 Spring的强大和灵活性不用再强调了.而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要 ...

  8. 逆向基础 C++ Primer Plus 第二章 开始学习C++

    C++ Primer Plus 第二章 开始学习C++ 知识点梳理 本章从一个简单的C++例子出发,主要介绍了创建C++程序的步骤,以及其所包含的预处理器编译指令.函数头.编译指令.函数体.注释等组成 ...

  9. wxWidgets源码分析(3) - 消息映射表

    目录 消息映射表 静态消息映射表 静态消息映射表处理过程 动态消息映射表 动态消息映射表处理过程 消息映射表 消息是GUI程序的核心,所有的操作行为均通过消息传递. 静态消息映射表 使用静态Event ...

  10. CSS元素层级的概念及性质

    元素的层级的介绍 什么是元素的层级 通过z-index可以改变开启定位元素的层级 父元素的层级再高也不会遮盖住子元素 元素的层级的介绍 什么是元素的层级 当元素开启定位后就会是元素提升一个层级,网页是 ...