MySQL进阶难度知识点分析

        以下为本人在阅读《MySQL是怎样运行的:从根儿上理解MySQL》这本书时对一些难度和重点的笔记,主要用于个人学习使用,内容可能存在出入,望理性食用~

1. sql执行流程

        一条sql的执行流程大致可分为客户端获取与数据库服务器的连接,然后查询缓存(MySQL 8.0之后移除),解析和优化,最后交给存储引擎进行具体数据的读取与写入。

        其中解析是指语法分析、词法分析、语义分析等,解析一条sql语句是否有语法错误,确定其查询的是哪个表,条件是什么,是否有索引等,然后优化器会进行优化,选择最优的执行计划,通过explain可以查看执行计划。

2. MySQL的内存结构

        存储引擎与硬盘的I/O通过中间的内存进行交互,页是内存与磁盘进行交互的基本单位,一个页中包含多干条记录,InnoDB中页的大小一般为16KB。存储引擎中有不同的页,有的页存放表结构,有的页存放Insert Buffer、有的页存放undo日志等,其中存放记录的页称为索引页,也可称为数据页

        16KB的页中包含不同的分区,每个分区有不同的功能,其中存放实际记录的分区称为User Records,未插入数据时为空,当插入数据时会从Free Space(未使用空间)中分一部分空间给User Recods来存放数据,当Free Space为0,仍有数据插入时,则插入到其他页中。

        页中还包含存放表信息的File Headers和存放页信息的Page Headers,具体分区情况如下:

        一条记录中,不仅包含实际的字段数据,还包含其他数据,比如记录的头信息、真实数据中的NULL值情况等,同时还要三个隐藏列:row_idtransaction_idroll_pointer。其中row_id是指当表中没有指定主键且不包含唯一索引时,会自动根据记录的物理存储顺序创建一个row_id用于记录的排序使用,transaction_id是事务id,roll_pointer是回滚指针。

        16KB的页中存储若干条记录项,这些记录根据主键id排序,每条记录之间使用单链表进行连接(next_record字段记录下一条记录的地址偏移量,用于查找下一条记录),为便于查询每条记录,不用每次查询都遍历所有的记录,将所有记录项按块进行分组,每个分组对于一个槽,这些槽(页面目录中的这些地址偏移量被称为)记录了该分组中主键id最大的位置,页中的所有槽构成了页目录,通过二分法查找页目录可以快速定位到所查记录项所在分组,然后通过next_record遍历该槽中的各个记录查找即可,以此来提高查询效率。具体来说,在一个完整的页中,每隔6条数据就会有一个Slot。

        同时记录项中有个delete_mask属性,用于逻辑删除使用,即值为0表示未删除,为1表示已删除,因为没从页中实际删除一条记录,移除该数据后需要从磁盘中重新进行I/O读取数据,效率较低,因此设置逻辑删除属性。

3. 为什么要有索引?

        每个数据页中的记录会按照主键的大小通过单链表进行连接,各个数据页通过双向链表进行连接。因为页的大小有限,一张表的数据量较大时,需要很多页来存储,当没有使用索引的情况下,每次查找一条记录时,只能从头遍历所有的页,来确定该记录存在于哪个页中,然后在页中二分查找来找到对应的记录,时间复杂度很高。

        参照AVL平衡二叉树的查找方式,MySQL的索引使用B+树进行降低查找的时间复杂度。在B+树中,非叶子结点存储了每个页中的最小主键值和页号,通过最小键值可以判断要查找的键值应该存在于哪个页中,通过页号可以直接定位到所要查找的页,使得每次查找只需从根节点比较主键的值,然后依次比较每个结点的键值,最后找到该记录存在于哪个叶子节点中,在该叶子节点中使用二分查找即可。

4. 页之间为什么要用双链表进行连接?

        因为当频繁的插入或删除数据时,页内的数据量会进行变化,当页内存储的数据量太小或者太大导致需要增加新叶或删除当前页时,为保证记录按照主键有序排列,需要进行页分裂,因此需要知道当前页的前后页的位置,故需要使用双向链表进行连接。

5. 回表的缺点

        因为非聚族索引的叶子节点只存放索引的键值和主键的值,不存放具体的数据,因此在使用非聚族索引如二级索引查数据时,会先根据二级索引查到该数据的主键值,然后到聚族索引中根据该主键值找到具体的数据信息,这种二次查表的过程就是回表,回表会导致查询效率降低,需要额外再查一次表。

        其次回表会导致随机IO,索引的叶子节点中的记录项是根据顺序依次排放的,它们在磁盘中的存储是相连的,因此根据查询的索引键值可以集中的将查询结果从磁盘中读取出来,这种读取方式称为顺序IO,效率高。而在回表查询时,每个索引键值对应的主键值是随机分布的,根据主键值再去聚族索引中查找不同的页中的记录项,这种读取方式称为随机IO,导致与磁盘IO次数增大,效率降低。

6. 使用索引的注意事项

  1. 对于联合索引进行查询时,查询条件要满足最左匹配原则。
  2. 用于排序的情况只有同升或同降才能适用索引,一升一降无法使用索引。
  3. 右模糊匹配适用索引,左模糊和全模糊不适用。
  4. 只对查询、排序或分组字段建立索引,而不是根据查询的结果建立索引。
  5. 索引列的类型尽可能的小,页的大小一定,主键值越小存储的记录项就越多。
  6. 为了尽可能少的让聚族索引发生页面分裂和记录移位的情况,建议让主键拥有AUTO_INCREMENT属性。
  7. 使用到索引的搜索条件和没有使用该索引的搜索条件使用OR连接起来后是无法使用该索引的。

7. Buffer Pool缓存区

        通过前面的知识可以知道InnoDB是以页为单位来存储和读取数据的,数据存储在磁盘中,当需要查询页中的某条数据时,会从磁盘中将相应的整页加载到内存当中,然后在内存中对该数据进行读写操作。而操作完成后并不会立即将该页对应的内存空间释放掉,而是将其缓存起来,以便下次查询到相同的数据时直接进行读取,省去了磁盘IO的开销。

        这个用于缓存磁盘中的页的区域被称为Buffer Pool(中文名是缓冲池,它是MySQL向操作系统申请的一片连续的空间,在MySQL服务器启动时进行初始化,默认空间大小为128M同时为了更好的管理Buffer Pool中的缓存页,每个缓存页都有其对应的控制信息这些控制信息包括该页所属的表空间编号、页号、缓存页在Buffer Pool中的地址、链表节点信息等,每个缓存页对应的控制信息占用的内存大小是固定的,将每个页对应的控制信息所占用的一块内存称为控制块,故一个页对应一个控制块,Buffer Pool对应的内存空间如下:

        刚开始时Buffer Pool内不存放任何数据,只是有空闲的一个个控制块和对应的缓存页构成,随着程序的运行不断有磁盘上的页被加载进该内存空间,那如何来确定Buffer Pool中哪些缓存页是空闲的,哪些已经被使用了呢?因此需要使用free链表来进行管理,其记录了所有空间缓存页的情况(将其对应的控制块放入到链表中),刚开始时所有缓存页均空闲,其对应的控制块都在free链表上,每当需要从磁盘中加载一个页到Buffer Pool中,就从free链表中取一个空闲的缓存页对应的控制块,并将其对应的控制块信息填上,然后从free链表中移除该控制块,表示当前缓存页已被使用。

        如果当我们访问页时,该页已经存在Buffer Pool中,如何确定其已存在呢?如何定位它的位置?

        最高效的方式就是在O(1)的时间复杂度内查询到,故可以使用哈希表,通过key快速找到其对应的value,表空间号 + 页号作为key缓存页作为value创建一个哈希表,在需要访问某个页的数据时,先从哈希表中根据表空间号 + 页号看看有没有对应的缓存页,如果有,直接使用该缓存页就好,如果没有,那就从free链表中选一个空闲的缓存页,然后把磁盘中对应的页加载到该缓存页的位置。

        再来考虑,当我们如何修改了Buffer Pool中的缓存页内的数据时,如何将其对应的页同步到更新到磁盘中去,防止出现脏页MySQL使用flush链表来存储脏页,将凡是修改过的缓存页对应的控制块都会作为一个节点加入到一个链表中,待之后的某个时刻同步到磁盘上。

        那么如果当Buffer Pool中的空间满了,依然有数据要从磁盘加载到该空间中该怎么办,一个很好的思路是将最近最少使用的缓存页释放掉,然后放入新的缓存页,因此根据该规则需再创建一个LRU链表,当我们需要访问某个页时,可以这样处理LRU链表

  • 如果该页不在Buffer Pool中,在把该页从磁盘加载到Buffer Pool中的缓存页时,就把该缓存页对应的控制块作为节点塞到LRU链表头部
  • 如果该页已经缓存在Buffer Pool中,则直接把该页对应的控制块移动到LRU链表头部

        也就是说:只要我们使用到某个缓存页,就把该缓存页调整到LRU链表的头部,这样LRU链表尾部就是最近最少使用的缓存页喽~ 所以当Buffer Pool中的空闲缓存页使用完时,到LRU链表的尾部找些缓存页淘汰就OK啦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/402864.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaEE精炼宝库】网络原理基础——UDP详解

文章目录 一、应用层二、传输层2.1 端口号:2.2 UDP 协议:2.2.1 UDP 协议端格式:2.2.2 UDP 存在的问题: 2.3 UDP 特点:2.4 基于 UDP 的应用层协议: 一、应用层 我们 Java 程序员在日常开发中,最…

【排序篇】插入排序与选择排序

🌈个人主页:Yui_ 🌈Linux专栏:Linux 🌈C语言笔记专栏:C语言笔记 🌈数据结构专栏:数据结构 文章目录 1. 排序的概念及其应用1.1 排序的概念1.2 排序的应用场景1.3 常见的排序算法 2.常…

Vue3+vite+ts 项目使用mockjs

1、安装mockjs npm i mockjs 2、安装vite-plugin-mock npm i vite-plugin-mock -D 3、安装axios npm i axios 4.在src目录下创建mock文件夹,在文件夹内创建login.ts等文件,并在文件夹内放置以下内容(注:URL要和真实请求地址保持一致&am…

走向绿色:能源新选择,未来更美好

当前,全球范围内可再生能源正经历着从辅助能源向核心能源的深刻转型,绿色能源日益渗透至居住、出行、日常应用等多个领域,深刻影响着我们的生活方式,使我们能够更加充分地体验清洁能源所带来的优质生活。 一、绿色能源与“住” …

搭建知识中台:让企业告别低效率

在当今这个信息爆炸、知识更新日新月异的时代,企业面临着前所未有的挑战与机遇。如何在浩瀚的信息海洋中高效筛选、整合并利用知识资源,成为决定企业竞争力的关键因素之一。因此,搭建知识中台,构建企业知识管理的核心枢纽&#xf…

day 28 HTTP协议

一、TCP粘包问题 TCP发送数据是连续的,两次发送的数据可能粘连成一包被接收到 解决粘包问题方法: 1.接收指定长度:(不稳定) 2.睡眠:(效率低) 让每次…

19010 最小的特殊数字

### 详细分析 1. 读取输入的N和K,以及N个数字。 2. 使用回溯算法生成所有可能的数字组合。 3. 对于每个组合,检查是否满足没有前置0且能被K整除。 4. 记录满足条件的最小数。 5. 输出满足条件的最小数,如果没有满足条件的数输出-1。 ### 代码…

java流程控制之分支结构(附有案例说明)

顺序结构:从上到下依次执行 前向引用 分支结构:根据条件选择的执行某段代码 1.if -else 结构 分支结构 if-else 1、格式1 if(条件表达式){ 语句块 } 2、格式2 if(条件表达式){ 语句块&#xff1b…

鸡爪全自动包冰衣设备:

一、快速冷冻,效率高 速冻挂冰机是一种能够快速降温并迅速冷冻食品的冷藏设备。其采用强制循环风冷技术,可以将食品迅速降温到所需温度,使食品更加新鲜。相比于传统的冷冻方式,速冻挂冰机的速度更快,效率更高&#xf…

2021年上半年网络工程师考试上午真题

2021年上半年网络工程师考试上午真题 网络工程师历年真题含答案与解析 第 1 题 以下关于RISC和CISC计算机的叙述中,正确的是( )。 (A) RISC不采用流水线技术,CISC采用流水线技术(B) RISC使用复杂的指令,CISC使用简…

超级外链工具,可发9600条优质外链

超级外链工具,是一款在线全自动化发外链的推广工具。使用本工具可免费为网站在线批量增加外链,大大提高外链发布工作效率,是广大草根站长们必备的站长工具。 外链工具只是网站推广的辅助工具,一般适用于短时间内无法建设大量外链…

欧拉远程桌面 安装tigervnc

注意:安装远程tigevnc前提必须已经安装桌面环境,以下为ukui桌面环境,dde稍有区别; 1、关闭selinux 注意:selinux为安全措施也可以加入对应规则 setenforce 0 sed -i s/^SELINUXenforcing.*/SELINUXdisabled/ /etc/sel…

坚鹏讲人才第12期:引领数字化未来—数字化人才与导师共赢之路

坚鹏讲人才第12期:引领数字化未来—数字化人才与导师共赢之路 ——抢占名额先机 成为坚鹏弟子 加速数字化转型 数字化浪潮汹涌而至,你是否感到迷茫、困惑、焦虑?想不想一脚油门冲进未来,和我一同探寻数字化人才的奥秘&#xf…

基于STM32开发的智能温室控制系统

基于STM32开发的智能温室控制系统 目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 系统初始化传感器数据采集控制与状态指示Wi-Fi通信与远程监控应用场景 农业温室智能控制室内植物养护管理常见问题及解决方案 常见问题解决方案结论 1. 引…

WebRTC音视频开发读书笔记(一)

一、基本概念 WebRTC(Web Real-Time Communication,网页即时通信)于2011年6月1日开源,并被纳入万维网联盟的W3C推荐标准,它通过简单API为浏览器和移动应用提供实时通信RTC功能。 1、特点 跨平台:可以在Web,Android、…

C# VisionPro 海康相机SDK源代码

运行界面如下所时: 实时图像效果如下: Winform窗体代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Fo…

LabVIEW光纤管道泄漏检测系统

光纤管道泄漏定位系统利用干涉型光纤传感器和数据采集卡进行信号获取与处理,实现了高灵敏度的泄漏点定位。通过软件对泄漏信号进行实时降噪处理和数据库管理,提高了系统的自动化和智能化水平。 项目背景: 长输管道在石油、天然气等行业中发挥…

XSS和DOM破坏案例

XSS案例 环境地址&#xff1a;XSS Game - Learning XSS Made Simple! | Created by PwnFunction 1.Ma Spaghet! 源码&#xff1a; <!-- Challenge --> <h2 id"spaghet"></h2> <script>spaghet.innerHTML (new URL(location).searchParam…

Python爬虫——某网站的视频数据

一、选题背景 1.背景 随着大数据时代的来临&#xff0c;网络爬虫在互联网中的地位将越来越重要。互联网中的数据是海量的&#xff0c;如何自动高效地获取互联网中我们感兴趣的信息并为我们所用是一个重要的问题&#xff0c;而爬虫技术就是为了解决这些问题而生的。对于身为数据…

【业务场景实战】你知道布隆过滤器怎么用吗?

布隆过滤器想必大家都听过&#xff0c;背过Redis面试题的兄弟应该都知道&#xff0c;布隆过滤器是解决缓存穿透问题的一种方法。但可能很少用过 布隆过滤器主要是为了解决海量数据的存在性问题。对于海量数据中判定某个数据是否存在且容忍轻微误差这一场景&#xff08;比如缓存…