一文搞懂MySQL基础框架

看了《MySQL高性能》以及几位博客大佬的博客。概要总结一下自己的理解。


先给出MySQL基本框架示意图,这张图的风格很喜欢,目前还不知道用什么画出来的,先用一下

在这里插入图片描述

咋一看图好像有点复杂,好像乱七八糟的。

不慌不慌,我们慢慢来,保证这篇看完就立马能大致全部了解了。

在这里插入图片描述

一般可以把MySQL分为Server层和存储引擎层两部分。

这一篇主要把Server层给弄清楚就可。

  • Server层:包含了连接器、查询缓存、分析器、优化器、执行器等,这里涵盖了MySQL的大多数核心功能区以及所有的内置函数。

    • 内置函数:日期,时间,数学和加密函数等;
    • 所有的跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。
  • 存储引擎层:负责着数据的存储和提取,并提供了读写接口。不同的引擎有着各自的方式。

    • create table时如果不指定引擎类型,默认使用的就是InnoDB。

接下来就是server层了。

一、连接器

功能就是负责跟客户端建立连接,获取权限,维持和管理连接。我们可以通过这个连接器呢,把客户端和server层连接起来,从而登录到mysql。

  • 连接过程
    • 经典的TCP握手之后,服务器会开始验证身份。这个时候要用到我们输入的用户名和密码
    • 用户名密码正确,连接器就会回到权限表里找到我们所拥有的权限。之后在这个连接面里的权限判断逻辑,都会依赖于此时读到的权限。
  • 连接完成之后
    • 如果不进行后续操作,这个连接就会空闲下来。可以使用show processlist命令来查看它。
    • 若很长时间都没有动静,那么连接器就会自动断开,这个时间默认的是8小时,是由wait_timeout控制的。

报告:我想修改wait_timeout时间,八小时太短了,满足不了我。

在这里插入图片描述

虽然很诧异,但是这是没有问题的啦

wait_timeout这个当然是可以手动更改的,更改方法如下

show global variables like 'wait_timeout'; -- 可查看当前wait_timeout时间为多少;
set global wait_timeout=36000; -- 修改wait_timeout为36000;
-- 当然咱们有图有真相。

在这里插入图片描述

关于上述的连接过程中连接器需要读的部分权限表

在这里插入图片描述

目前知道的这四个权限表

  • user权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的。

  • db权限表:记录各个帐号在各个数据库上的操作权限。

  • table_priv权限表:记录数据表级的操作权限。

  • columns_priv权限表:记录数据列级的操作权限。

关于长连接和短链接

  • 长连接:指的就是长时间使用同一连接的情况,也就是连接成功后,长时间保持客户端与服务端的连接状态。

    可表示为:

    连接 -> 数据传输 -> 保持连接 -> 数据传输 -> 保持连接 … -> 关闭连接;

    因此这就需要长连接在没有数据通信时,定时发送数据包,以维持连接状态。

  • 短链接:在没有数据传输时直接关闭就行了。

    可表示为:

    连接 -> 数据传输 -> 关闭连接;

由于建立连接过程很复杂,所以我们尽量要减少建立连接的动作,也就是尽量使用长连接。

但是呢但是 长连接也存在着一个问题

  • 如果全部使用长连接的话,会发现MySQL占用内存特别快。

    为什么呢?

    • 因为MySQL在执行的时候临时使用的内存时管理在连接对象里面的,这些资源只有在连接断开的时候会释放。所以若长连接链积累下来,就可能会导致内存占用太大。然后呢,就会被系统给强制杀死。

    表现出来就是MySQL会异常重启

    当然也有着解决方案

    • 定期断开长连接。

    不过如果使用的时MySQL5.7或者更高的版本的话。可以通过执行mysql_reset_connection来重新初始化链接资源。好的地方在这个过程不需要重连和重新做权限验证,而且还会将连接恢复到刚刚创建完时的状态。妙哉妙哉

查询缓存

简介一下:就是之前查询过的语句被记录下来了,当你再次使用那个语句时,就不需要进行下面的分析优化执行了,直接在缓存中找即可。

缓存是怎么被存的呢?

  • 之前执行过的语句以及结果会以key-value对的形式,被直接存放在内存中。key是查询的语句,value是查询的结果。

看上去效率可高了呢。。

但其实大多数情况下我们都会不被建议使用查询缓存。

???为什么,明明这么好用的东西啊

在这里插入图片描述

别急别急看这里 (经过寻找各种大佬博客本蒻j终于找到了答案)

  • 因为查询缓存的失效非常的频繁,只要有对一个表的更新,这个表上的所有查询缓存都会被清空。这就造成了这么一种现象:明明你费劲把结果存了起来,结果还没使用呢,就被一个更新全部清空了。对于频繁需要更新的数据库来说,查询缓存的命中率会非常的低。当然在某些静态表上,就是很久才会更新一次的表上,比如一个系统配置表,就比较适合使用查询缓存。

当不想使用查询缓存的时候,可以将参数query_cache_type设置成DEMAND。

这之后对于默认的SQL语句都不适用查询缓存了。当有些你确定要使用查询缓存的语句,可以用SQL_CACHE显示指定。比如

select sql_cache * from employee where salary = 3000;

ps:MySQL 8.0版本之后直接就将查询缓存的整块功能删掉了 ,也就是说从8.0开始就彻底没有这个功能了。

在这里插入图片描述

分析器

简介:如果没有命中缓存的话,就会开始真正的执行SQL语句了。分析器中简单的说包含了词法分析和语法分析。

给个例子分析一下

select * from employee where salary = 3000;
  • 词法分析:分析器通过语法分析器,识别出了里面的字符分别是什么,代表着什么。

    比如上面例子中,会将select这个关键字识别出来,首先知道这是条查询语句,然后把employee识别成表面employee,再把字符串salary识别成列ID,以此类推。最后识别出每个词。

  • 语法分析:根据词法分析的结果,语法分析器会根据语法规则,判断输入的这个SQL语句是否满足MySQL语法。如果发现不满足,就会收到“you have an error in your SQL syntax”的错误提醒。

优化器

简介:经过上面的分析器,MySQL知道了需要做什么事儿了,但在开始做之前,还需要经过优化器的处理。

大概两个优化

  • 优化器在表里面有多个索引时,决定使用哪个索引。
  • 在一个语句有夺标关联(join)的时候,决定各个表连接的顺序。

选择更快的索引好理解,稍微有点绕口的时决定各个表连接的顺序。

举个栗子

select * from a join b using(id) where a.c=10 and b.d=20;

这个关联中

  • 既可以先从表a中取出c=10的记录的ID值,再根据ID值关联到表b,再判断b里面d的值是否等于20。

  • 也可以先从表b中取出d=20的记录的ID值,再根据ID值关联到表a,再判断a里面c的值是否等于10。

用不同的执行方法的逻辑结果是一样的,但是执行的效率会有不同。优化器就会决定选择使用哪一种方案,当然回旋执行效率高的。

执行器

简介:通过分析器知道了我是谁,我要干什么,通过优化器知道了我要怎么干我干的事情。于是到了执行器阶段,就要开始干活啦!

当然也不是说干就干,人家还是很正经有流程的在这里插入图片描述

  • 1、判断对这个表employee有没有查询的权限,如果没有,那当然不行的了,会返回没有权限的错误❌
  • 2、要是判断出来有权限呢,就会打开表继续执行,打开的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。再提一嘴,默认引擎是InnoDB。然后就会顺着下去,根据引擎提供的流程,执行下去,最后找到我们想要的。

至此,整个流程就结束了。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值