逻辑架构图
客户端访问MySQL服务器前首先要建立TCP连接
三次握手建立连接成功后,MySQL服务器对TCP传输过来的账号密码做 身份认证 、 权限获取
语法树
,会根据数据字典丰富查询语法树执行计划
使用哪些索引
进行查询,最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询两次查询语句完全一样
就命中缓存,不用再去存储文件里查了插件式存储引擎层( Storage Engines), 真正的负责了MySQL中数据的存储和提取,对物理服务器级别维护的底层数据执行操作 ,不同的存储引擎有不同的功能
常见的有:MyISAM,InnoDB,Memory
所有的数据,数据库、表的定义,表的每一行的内容,索引,都是存在 文件系统
上,以 文件
的方式存 在的,并完成与存储引擎的交互。
当然有些存储引擎比如InnoDB,也支持不使用文件系统直接管理裸设备,但现代文件系统的实现使得这样做没有必要了。在文件系统之下,可以使用本地磁盘,可以使用 DAS、NAS、SAN 等各种存储系统。
架构可以简化为下图:
简化的三层结构:
如图:
大多数情况查询缓存就是个鸡肋。因为MySQL中的查询缓存,不是缓存查询计划,而是查询对应的结果。
这就意味着:两个查询请求在任何字符上的不同(例如:空格、注释、 大小写),都会导致缓存不会命中。因此 MySQL 的查询缓存命中率不高,就是个鸡肋
在解析器中对 SQL 语句进行语法分析、语义分析。
分析器先做词法分析
。对你输入的多个字符串组成的SQL语句进行分析,识别出每个字符串分别是什么,代表什么。例如:吧"select"这个关键字识别出来
分析器接下来做语法分析
。语法分析器根据语法规则判断你的SQL是否满足MYSQL的语法,如果正确,就会返回一颗语法树:
在优化器中会确定 SQL 语句的执行路径,比如是根据 全表检索
,还是根据 索引检索
等
优化器中有逻辑优化
和物理优化
举例:
select * from test1 join test2 using(ID)
where test1.name='zhangwei' and test2.name='mysql高级课程';
方案1:可以先从表 test1 里面取出 name='zhangwei’的记录的 ID 值,再根据 ID 值关联到表 test2,再判 断 test2 里面 name的值是否等于 ‘mysql高级课程’。
方案2:可以先从表 test2 里面取出 name=‘mysql高级课程’ 的记录的 ID 值,再根据 ID 值关联到 test1, 再判断 test1 里面 name的值是否等于 zhangwei。
这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案
。优化器阶段完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段。
截止到现在,还没有真正去读写真实的表,仅仅只是产出了一个执行计划。于是就进入了执行器阶段
在执行之前需要判断该用户是否 具备权限
。如果没有,就会返回权限错误。如果具备权限,就执行 SQL 查询并返回结果。在 MySQL8.0 以下的版本,如果设置了查询缓存,这时会将查询结果进行缓存。
SQL 语句在 MySQL 中的流程是: SQL语句→查询缓存→解析器→优化器→执行器
。
InnoDB
存储引擎是以页为单位来管理存储空间的,我们进行的增删改查操作实际上是在访问页面。
我们都知道磁盘IO需要消耗很多时间,在内存中操作效率就会高得多。如果我们可以在内存中进行修改,然后再写入磁盘,这样效率会高得多。
为了实现这种方式 ,DBMS 会申请 占用内存来作为数据缓冲池
,在真正访问页面之前,需要把在磁盘上的页缓存到内存中的 Buffer Pool 之后才可以访问。这样做的好处是可以让磁盘活动最小化,从而 减少与磁盘直接进行 I/O 的时间
。
缓冲池和查询缓存是一个东西吗?不是。
缓冲池包括了数据页、索引页、插入缓冲、锁信息、自适应 Hash 和数据字典信息等。
缓冲池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响
。
查询缓存是提前把查询结果
缓存起来,这样下次不需要执行就可以直接拿到结果。
查询缓存条件苛刻,命中率低
缓冲池管理器会尽量将经常使用的数据保存起来,在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,这个过程称为将页“FIX”在缓冲池中。下一次再读相同的页时,首先判断该页是否在缓冲池中。若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。否则,读取磁盘上的页。
问:如果我们执行 SQL 语句的时候更新了缓存池中的数据,那么这些数据会马上同步到磁盘上吗?
答:不会,执行SQL语句首先会更新缓冲池上的内容,然后mysql后台会有一个线程按一定的频率将页面刷入硬盘中