思路
整篇的写作大概就是这样思路。一篇带你熟悉MySQL!篇幅很大,建议先关注,收藏!
整个篇幅的知识点全部缩减。为面试系列打造!如果想具体深入研究,请关注公众号浏览其他文章即可!
1. SQL是如何执行的
1.1 查询
平时我们都是关注SQL是如何执行的,但是有没有了解整个MySQL的结构呢?这里我们介绍一下
整个MySQL主要分两层。
- Service
- 存储引擎层
这两层主要由四部分构成
- 连接器
- 分析器
- 优化器
- 执行器
连接器: 校验用户身份信息,校验当前用户的SQL语句权限,管理SQL连接的通道
分析器: 词法分析,语法分析。用于处理客户端的SQL语句,分析处理完之后写入缓存,如果下次命中的话直接返回提高查询效率。
优化器: 生成执行计划,索引选择(这里可以完美解释我上面抛出的SQL执行问题)
执行器: 调用操作存储引擎,捞取数据。
大概介绍了MySQL每一种结构发挥的作用。这里扩展一下大家一直说的长连接和短连接的优化!
**长连接:**建立连接之后,如果客户端的有请求操作则一种使用同一个连接进行交互处理
**短连接:**建立连接之后,并且客户端执行完自己的需求之后,就关闭了连接。
长短连接总结: 数据库建立连接这个过程是比较复杂的,所以建立尽量减少使用短连接的方式,也就是尽量使用长连接。但是长连接是比较容易涨内存的。也会被系统误认为内存占用过大强行杀死。
优化方案: 可以采用定期断开长连接的方法优化。还可以通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证。
1.2 修改
首先要介绍两个日志。redo log 和 binlog。
redolog充当于我们平时生活中的记事本,备忘录。
binlog充当于阎王殿的生死簿。
数据库中也是一样。当进行数据修改操作时,不会立即修改到磁盘。如果是立即修改的话,对磁盘IO影响是比较大的。所以平时的修改操作都会先写到redo log
中,等系统认为不忙的时候再更新到binlog
中。
区别
- redolog是innodb引擎层特有的,binlog 是Server层自带的。
- redolog是物理日志,binlog是逻辑日志
- redolog记录在某个数据页上做了什么修改,binlog记录这个语句的原始逻辑。
- redolog循环写,binlog追加写
修改流程
update vip set name=‘欢少的成长之路’ where ID=2
- 先查找ID=2 这一行数据。查找方式有两种,一种是直接从表中取,另一种就是如果缓存中存在就直接走缓存
- 取到之后,直接修改
name=欢少的成长之路
写入新行 - 新行更新到内存中
- 写入redolog,并且当前处于prepare阶段
- 写入binlog
- commit提交事务
这里面可以跟面试官介绍一下两阶段提交,第四步和第五步为什么要分开写入呢?这个就是两阶段提交的精髓
目的是为了让数据保持一致 如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致,下面我们举例论证一下。
- 先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启,仍然能够把数据恢复回来,所以恢复后这一行 name 的值是
欢少的成长之路
。但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 name 的值就是欢少个人业务
,与原库的值不同。 - 先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 name 的值是
欢少个人业务
。但是 binlog 里面已经记录了把 name 从欢少个人业务
改成欢少的成长之路
这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这一行 c 的值就是欢少的成长之路
,与原库的值不同。
1.3 总结
上述就是一个SQL如何执行的介绍了,从查询与修改分别介绍了流程以及涉及到的知识点。最重要的就是两阶段提交了。如果面试官问你的话来个反证法差不多就过关啦
2. 索引结构
2.1 是什么
索引结构是MySQL最底层的数据处理结构了。主要分五块
- 哈希
- 链表
- 二叉树
- B树
- B+树
哈希
这个就是通过hash
算法,把每个数据都hash出一串key之后,然后存在数据页的某一个位置。如果出现了相同的key就是发生了哈希碰撞。这个后续在算法章节会详细介绍一下。
这里MySQL解决方案是采用链表+哈希的方式共同存储在一个槽中。
链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
二叉树
二叉树是一种树形结构,每个节点只有两颗子节点。它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树
红黑树
红黑树是一种 特定类型的二叉树,它是在计算机科学中用来组织数据比如数字的块的一种结构。若一棵二叉查找树是红黑树,则它的任一子树必为红黑树。
红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对之进行平衡的代价较低, 其平均统计性能要强于 AVL 。
由于每一棵红黑树都是一棵二叉排序树,因此,在对红黑树进行查找时,可以采用运用于普通二叉排序树上的查找算法,在查找过程中不需要颜色信息。
B+树
B+树是B树的一个升级版,相对于B树来说B+树更充分的利用了节点的空间,让查询速度更加稳定,其速度完全接近于二分法查找
2.2 优缺点
哈希
- 优点: 哈希索引在解决单值查询的时候是非常快的,时间复杂度是O(1)。
- 缺点: 但是不支持范围查询,所以当前MySQL中也应用到了哈希索引,但是并不是默认索引。
链表
- 优点 :上面我们介绍到了,它是非连续的,非顺序的。所以在进行数据修改操作时,无需找到当前节点的前后进行移动操作。直接把数据修改了之后,把指针指向最新节点就好了。
- 缺点 : 如果当一个链表过于庞大的话,我们查询数据时,要一个一个遍历。链表没有数组那种的高效查询,也没有树形结构的对半查询。
二叉树
- 优点 : 查询数据时,采用对半查找。查询效率非常高。解决了链表留下来的难题。
- 缺点 : 当一个数出现持续递增时,会有倾斜的状态,比如 0 1 2 3 4 5 6 。这样就是一个倾斜树,查询效率与链表相当。不符合MySQL的大数据存储
红黑树
- 优点 : 一定程序上解决了二叉树偏移的问题,但是问题解决的不够根本
- 缺点 : 出现了层级较多这个问题。层级较多会影响查询性能。
B+树
- 优点 : 在B树的基础上作了优化,也是红黑树之后的一个进化版。主要优化点就是数据节点的自旋。在插入时,当节点树大于某一个限制后会自动自旋,变成另一个节点树。而且具有排序的功能。节点与节点之间有连接关系,这是对查询非常有利的。
2.3 总结
第二部分,大概介绍了MySQL的五个索引结构。从概念,到优缺点的介绍。通过优缺点为切入点进行分析了MySQL为什么会以B+树为默认索引结构的原因。
3. 内部索引
3.1 聚簇索引
概念
聚簇索引也是主键索引。一个表只能有一个聚簇索引。当表有聚簇索引时,数据行是保存在索引的叶子页的。
优点
数据访问更快,数据都保存在一棵树上,可以避免为了查询其他列进行回表操作。
缺点
聚簇索引极大的提高了IO密集型应用的性能,但是如果都放入内存中,访问的顺序就没那么必要了。聚簇索引也就失去了优势。
更新聚簇索引列的代价很高,因为会强制InnoDB将每个被更新的行移动到新的位置。
基于聚簇索引的表在插入新行,或者主键被更新导致需要移动行的时候,可能面临“页分裂”的问题。当行的主键值要求必须将这一行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳该行,这就是一次分裂操作。页分裂会导致表占用更多的磁盘空间。
聚簇索引可能导致全表扫描变慢,尤其是行比较稀疏,或者由于页分裂导致数据存储不连续的时候
3.2 非聚簇索引
概念
非聚簇索引也是二级索引。
叶子节点不存储数据,存储的是数据行地址,也就是说根据索引查找到数据行的位置再去磁盘查找数据,这就有点类似一本书的目录,比如要找到第三章第一节,那就现在目录里面查找,找到对应的页码后再去对应的页码看文章。
优缺点
非聚簇索引在做查找时,往往需要二次查询。第一次查找到主键值,再通过主键值找到数据行对应的数据页,再通过数据页中的Page Directory找到数据行。
一个表中可以存在多个非聚簇索引。
如果主键比较大的话,那非聚簇索引将会变得更大,因为非聚簇索引的叶子节点存储的是主键值,过长的主键值,会导致非叶子节点占用更多的物理空间
3.3 普通索引
最基本的索引,没有任何限制,是我们经常使用到的索引。他的任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHEREcolumn=)或排序条件(ORDERBYcolumn)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引
3.4 唯一索引
与普通索引类似,不同的是,唯一索引的列值必须唯一,但允许为空值。主键索引是特殊的唯一索引,不允许有空值。
3.5 联合索引
将几个列作为一条索引进行检索,使用最左匹配原则。举一个用户登录的例子。可以把登录账号和登录密码设为联合索引。这样可以提供性能的同时,节省索引的维护成本。
3.6 索引下推
索引下推是在MySQL5.6引入的优化。可以在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表字数。
3.7 总结
第三部分大概介绍了MySQL内部索引的概念,优缺点,应用等。面试中常问的就是聚簇索引与非聚簇索引的区别。所以这里也是把这两块写的最详细的地方。
4. 总结
文章大概几万字,每一篇大概3000字。后续还有3-4篇会发表。觉得还可以的友友的,点赞,关注。 发表看法的友友们,一经采纳会赠送书籍,大厂面试资料等福利