mysql的基础技术架构

下图是 MySQL 的基本架构示意图,从中你可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程。

 

在这里插入图片描述

 MySQL 可以分为 Server 层存储引擎层两部分。

Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等,还有一个通用的日志模块 binlog。

存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。InnoDB 引擎有自有的日志模块 redolog。

不同的存储引擎共用一个Server 层。
 

Server 层基本组件

连接器

连接器主要和身份认证和权限相关的功能相关。

主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作,如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。
 

查询缓存

MySQL 8.0 版本后移除。

查询缓存主要用来缓存之前所执行的 SELECT 语句以及该语句的结果集。

连接建立后,执行查询语句的时候,会先查询缓存,MySQL 会先校验这个 sql 是否执行过,以 Key-Value 的形式缓存在内存中,Key 是查询语句,Value 是结果集。如果缓存 key 被命中,就会直接返回给客户端,如果没有命中,就会执行后续的操作,完成后也会把结果缓存起来,方便下一次调用。当然在真正执行缓存查询的时候还是会校验用户的权限,是否有该表的查询条件。

MySQL 查询不建议使用缓存,因为查询缓存失效在实际业务场景中可能会非常频繁,假如对一个表更新的话,这个表上的所有的查询缓存都会被清空。对于不经常更新的数据来说,使用缓存还是可以的。

所以,一般在大多数情况下都是不推荐去使用查询缓存的。

MySQL 8.0 版本后删除了缓存的功能,官方也是认为该功能在实际的应用场景比较少,所以干脆直接删掉了。
 

分析器

MySQL 没有命中缓存,就会进入分析器,分析器主要是用来分析 SQL 语句是来干嘛的,分析器也会分为几步:

第一步,词法分析,一条 SQL 语句有多个字符串组成,首先要提取关键字,比如 select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。

第二步,语法分析,主要就是判断你输入的 sql 是否正确,是否符合 MySQL 的语法。

完成这 2 步之后,MySQL 就准备开始执行了,但是如何执行,怎么执行是最好的结果呢?这个时候就需要优化器上场了。

优化器

优化器的作用就是以它认为的最优的执行方案去执行(有时候可能也不是最优),比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等。

可以说,经过了优化器之后可以说这个语句具体该如何执行就已经定下来。

执行器

当选择了执行方案后,MySQL 就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果

语句分析

查询语句


说了以上这么多,那么究竟一条 sql 语句是如何执行的呢? sql 可以分为两种,一种是查询,一种是更新(增加,更新,删除)。先分析下查询语句,语句如下:

select * from tb_student A where A.age='18' and A.name='张三';
1
分析下这个语句的执行流程:

先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限,在 MySQL 8.0 版本以前,会先查询缓存,以这条 sql 语句为 key 在内存中查询是否有结果,如果有直接缓存,如果没有,执行下一步。

通过分析器进行词法分析,提取 sql 语句的关键元素,比如提取上面这个语句是查询 select,提取需要查询的表名为 tb_student,需要查询所有的列,查询条件是这个表的 id=‘1’。然后判断这个 sql 语句是否有语法错误,比如关键词是否正确等等,如果检查没问题就执行下一步。

接下来就是优化器进行确定执行方案,上面的 sql 语句,可以有两种执行方案:

a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是 18。
b.先找出学生中年龄 18 岁的学生,然后再查询姓名为“张三”的学生。

那么优化器根据自己的优化算法进行选择执行效率最好的一个方案(优化器认为的,有时候不一定最好)。那么确认了执行计划后就准备开始执行了。

进行权限校验,如果没有权限就会返回错误信息,如果有权限就会调用数据库引擎接口,返回引擎的执行结果。

更新语句


接下来看一条更新语句如何执行的,sql 语句如下:

update tb_student A set A.age='19' where A.name=' 张三 ';
1
来给张三修改下年龄,在实际数据库肯定不会设置年龄这个字段的,不然要被技术负责人打的。

因为年龄每年都会变的,可以保存一个出生日期,就可以直接算出来,而不用维护一个每年都要变的字段。

其实这条语句也基本上会沿着上一个查询的流程走,只不过执行更新的时候肯定要记录日志,这就会引入日志模块,MySQL 自带的日志模块是 binlog(归档日志) ,所有的存储引擎都可以使用,InnoDB 引擎还自带了一个日志模块 redo log(重做日志),就以 InnoDB 模式下来探讨这个语句的执行流程。流程如下:

先查询到张三这一条数据,如果有缓存,也是会用到缓存。

然后拿到查询的语句,把 age 改为 19,然后调用引擎 API 接口,写入这一行数据,InnoDB 引擎把数据保存在内存中,同时记录 redo log,此时 redo log 进入 prepare 状态,然后告诉执行器,执行完成了,随时可以提交。

执行器收到通知后记录 binlog,然后调用引擎接口,提交 redo log 为提交状态。

更新完成。

为什么要用两个日志模块,用一个日志模块不行吗?

这是因为最开始 MySQL 并没有 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) ,MySQL 自带的引擎是 MyISAM,但是 redo log 是 InnoDB 引擎特有的,其他存储引擎都没有,这就导致会没有 crash-safe 的能力(crash-safe 的能力即使数据库发生异常重启,之前提交的记录都不会丢失),binlog 日志只能用来归档。

并不是说只用一个日志模块不可以,只是 InnoDB 引擎就是通过 redo log 来支持事务的。那么,又会有同学问,我用两个日志模块,但是不要这么复杂行不行,为什么 redo log 要引入 prepare 预提交状态?这里我们用反证法来说明下为什么要这么做:

先写 redo log 直接提交,然后写 binlog,假设写完 redo log 后,机器挂了,binlog 日志没有被写入,那么机器重启后,这台机器会通过 redo log 恢复数据,但是这个时候 binlog 并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。


先写 binlog,然后写 redo log,假设写完了 binlog,机器异常重启了,由于没有 redo log,本机是无法恢复这一条记录的,但是 binlog 又有记录,那么和上面同样的道理,就会产生数据不一致的情况。


如果采用 redo log 两阶段提交的方式就不一样了,写完 binglog 后,然后再提交 redo log 就会防止出现上述的问题,从而保证了数据的一致性。那么问题来了,有没有一个极端的情况呢?假设 redo log 处于预提交状态,binglog 也已经写完了,这个时候发生了异常重启会怎么样呢? 这个就要依赖于 MySQL 的处理机制了,MySQL 的处理过程如下:

判断 redo log 是否完整 (commit),如果判断是完整的,就立即提交。
如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如果完整就提交 redo log, 不完整就回滚事务。
这样就解决了数据一致性的问题。

总结


查询语句执行流程如下:权限校验(如果命中缓存)–> 查询缓存 —> 分析器 --> 优化器 —> 权限校验 —> 执行器 —> 引擎
更新语句执行流程如下:分析器 —> 优化器 —> 权限校验 —> 执行器 —> 引擎 —> redo log(prepare) —> binlog —> redo log(commit)

补充:

MySQL得到sql语句后,大概流程如下:

在这里插入图片描述

0.连接器负责和客户端进行通信
1.查询缓存:首先查询缓存看是否存在k-v缓存
2.解析器:负责解析和转发sql
3.预处理器:对解析后的sql树进行验证
4.优化器:得到一个执行计划
5.查询执行引擎:执行器执行语句得到数据结果集
6.将数据放回给调用端。

深入理解mysql的底层原理

mysql的常用引擎

1. InnoDB

InnoDB 的存储文件有两个,后缀名分别是 .frm 和 .idb,其中 .frm 是表的定义文件,而 idb 是数据文件。

InnoDB 中存在表锁和行锁,不过行锁是在命中索引的情况下才会起作用。

InnoDB 支持事务,且支持四种隔离级别(读未提交、读已提交、可重复读、串行化),默认的为可重复读;而在 Oracle 数据库中,只支持串行化级别和读已提交这两种级别,其中默认的为读已提交级别。

2. Myisam

Myisam 的存储文件有三个,后缀名分别是 .frm、.MYD、MYI,其中 .frm 是表的定义文件,.MYD 是数据文件,.MYI 是索引文件。

Myisam 只支持表锁,且不支持事务。Myisam 由于有单独的索引文件,在读取数据方面的性能很高 。

3、存储结构

InnoDB 和 Myisam 都是用 B+Tree 来存储数据的。

MySQL 的数据、索引存储结构

1. 数据存储的原理(硬盘)

信息存储在硬盘里,硬盘是由很多的盘片组成,通过盘片表面的磁性物质来存储数据。

把盘片放在显微镜下放大,可以看到盘片表面是凹凸不平的,凸起的地方被磁化,代表数字 1,凹的地方没有被磁化,代表数字 0,因此硬盘可以通过二进制的形式来存储表示文字、图片等的信息。

硬盘有很多种,但是都是由盘片、磁头、盘片主轴、控制电机、磁头控制器、数据转换器、接口、缓存等几个部分组成。

所有的盘片都固定在一个旋转轴上,这个轴即盘片主轴。

所有的盘片之间是绝对平行的,在每个盘片的盘面上都有一个磁头,磁头与盘片之间的距离比头发丝的直径还小。

所有的磁头连在一个磁头控制器上,由磁头控制器负责各个磁头的运动,磁头可沿盘片的半径方向移动,实际上是斜切运动,每个磁头同一时刻必须是同轴的,即从正上方往下看,所有磁头任何时候都是重叠的。

由于技术的发展,目前已经有多磁头独立技术了,在此不考虑此种情况。

盘片以每分钟数千转到上万转的速度在高速运转,这样磁头就能对盘片上的指定位置进行数据的读写操作。

由于硬盘是高精密设备,尘埃是其大敌,所以必须完全密封。

2. 数据读写的原理

硬盘在逻辑上被划分为磁道、柱面以及扇区。

磁头靠近主轴接触的表面,即线速度最小的地方,是一个特殊的区域,它不存放任何数据,称为启停区或者着陆区,启停区外就是数据区。

在最外圈,离主轴最远的地方是 “0” 磁道,硬盘数据的存放就是从最外圈开始的。

在硬盘中还有一个叫 “0” 磁道检测器的构件,它是用来完成硬盘的初始定位。

盘面

硬盘的盘片一般用铝合金材料做基片,硬盘的每一个盘片都有上下两个盘面,一般每个盘面都会得到利用,都可以存储数据,成为有效盘面,也有极个别的硬盘盘面数为单数。

每一个这样的有效盘面都有一个盘面号,按顺序从上至下从 0 开始编号。

在硬盘系统中,盘面号又叫磁头号,因为每一个有效盘面都有一个对应的读写磁头,硬盘的盘片组在 2-14 片不等,通常有 2-3 个盘片。

磁道

磁盘在格式化时被划分成许多同心圆,这些同心圆轨迹叫做磁道。

磁道从外向内从 0 开始顺序编号,硬盘的每一个盘面有 300-1024 个磁道,新式大容量硬盘每面的磁道数更多,信息以脉冲串的形式记录在这些轨迹中,这些同心圆不是连续记录数据,而是被划分成一段段的圆弧。

这些圆弧的角速度一样,由于径向长度不一样,所以线速度也不一样,外圈的线速度较内圈的线速度大,即同样的转速度下,外圈在同样时间段里,划过的圆弧长度要比内圈划过的圆弧长度大。

每段圆弧叫做一个扇区,扇区从 1 开始编号,每个扇区中的数据作为一个单元同时读出或写入。

磁道是看不见的,只是盘面上以特殊形式磁化了的一些磁化区,在磁盘格式化时就已规划完毕。

柱面

所有盘面上的同一磁道构成一个圆柱,通常称作柱面。

每个圆柱上的磁头由上而下从 0 开始编号,数据的读 / 写按柱面进行,即磁头读 / 写数据时首先在同一柱面内从 0 磁头开始进行操作,依次向下在同一柱面的不同盘面即磁头上进行操作。

只有在同一柱面所有的磁头全部读 / 写完毕后磁头才转移到下一柱面(同心圆再往里的柱面),因为选取磁头只需要通过电子切换即可,而选取柱面则必须机械切换,电子切换相当快,比在机械上的磁头向邻近磁道移动快得多。

所以,数据的读 / 写按柱面进行,而不按盘面进行,也就是说,一个磁道写满数据后,就在同一柱面的下一个盘面来写,一个柱面写满后,才移到下一个扇区开始写数据,读数据也按照这种方式进行,这样就提高了硬盘的读 / 写效率。

扇区

操作系统以扇区形式将信息存储在硬盘上,每个扇区包括 512 个字节的数据和一些其他信息,一个扇区有两个主要部分:存储数据地点的标识符和存储数据的数据段。

标识符就是扇区头标,包括组成扇区三维地址的三个数字:盘面号,柱面号,扇区号(块号)。

数据段可分为数据和保护数据的纠错码(ECC)。在初始准备期间,计算机用 512 个虚拟信息字节(实际数据的存放地)和与这些虚拟信息字节相应的 ECC 数字填入这个部分。

3. 访盘请求完成过程

1)确定磁盘地址(柱面号,磁头号,扇区号),内存地址(源 / 目):

当需要从磁盘读取数据的时候,系统会将数据的逻辑地址传递个磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区。

2)为了读取这个扇区的数据,需要将磁头放到这个扇区上方,为了实现这一点:

  • A. 首先必须找到柱面,即磁头需要移动对准相应磁道,这个过程叫做寻道,所耗费时间叫做寻道时间。

  • B. 然后目标扇区旋转到磁头下,即磁盘旋转将目标扇区旋转到磁头下,这个过程耗费的时间叫做旋转时间。

3)即一次访盘请求(读 / 写)完成过程由三个动作组成:

  • A. 寻道(时间):磁头移动定位到指定磁道。

  • B. 旋转延迟(时间):等待指定扇区从磁头下旋转经过。

  • C. 数据传输(时间):数据在磁盘与内存之间的实际传输。

4. 磁盘的读写原理

系统将文件存储到磁盘上时,按柱面、磁头、扇区的方式进行,即最先是第 1 磁道的第一磁头下的所有扇区,然后是同一柱面的下一个磁头……

一个柱面存储满后就推进到下一个柱面,直到把文件内容全部写入磁盘。

系统也以相同的顺序读出数据,读出数据时通过告诉磁盘控制器要读出扇区所在柱面号、磁头号和扇区号(物理地址的三个组成部分)进行。

5. 减少 I/O 的预读原理

由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费的时间,磁盘的存取速度往往是主存的几百分之一。

因此,为了提高效率,要尽量减少磁盘的 I/O。

磁盘往往不是严格地按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。

这样做的理论依据是计算机科学中著名的局部性原理:

  1. 当一个数据被用到时,其附近的数据一般来说也会被马上使用。

  2. 程序运行期间所需要的数据通常比较集中。

  3. 由于磁盘顺序读取的效率很高(不需要寻道时间,只需要很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高 I/O 效率。

预读的长度一般为页(Page)的整数倍。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储分割为连续的大小相等的块。

每个存储块称为一页(在许多操作系统中,页的大小通常为 4k),主存和磁盘以页为单位交换数据,当程序要读取的数据不在主存中时,会触发一个缺页异常。

此时系统会向磁盘发出读盘信息,磁盘会找到数据的起始位置并向后连续读取一页或几页的数据载入内存中,然后异常返回,程序继续运行。

6. MySQL 的索引

索引是一种用来实现 MySQL 高效获取数据的数据结构。

我们通常所说的在某个字段上建索引,意思就是让 MySQL 对该字段以索引这种数据结构来存储,然后查找的时候就有对应的查找算法。

建索引的根本目的是为了查找的优化,特别是当数据很庞大的时候,一般的查找算法有顺序查找、折半查找、快速查找等。

但是每种查找算法都只能应用于特定的数据结构之上,例如顺序查找依赖于顺序结构,折半查找通过二叉查找树或红黑树实现二分搜索。因此在数据之外,数据库系统还维护着满足特定查找算法的数据结构。

这些数据结构以某种方式引用数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

7. MySQL 的 B+Tree

目前大多数数据库系统及文件系统都采用 B-Tree 或其变种 B+Tree 作为索引结构。

B+ 树索引是 B+ 树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。B+ 树中的 B 代表平衡,而不是二叉。

因为 B+ 树是从最早的平衡二叉树演化而来的。B+ 树是由二叉查找树、平衡二叉树(AVLTree)和平衡多路查找树(B-Tree)逐步优化而来。

二叉查找树:左子树的键值小于根的键值,右子树的键值大于根的键值。

AVL 树:平衡二叉树(AVL 树)在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为 1。

平衡多路查找树(B-Tree):为磁盘等外存储设备设计的一种平衡查找树。

系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一磁盘块中的数据会被一次性读取出来,而不是按需读取。

InnoDB 存储引擎使用页作为数据读取单位,页是其磁盘管理的最小单位,默认 page 大小是 16k。

系统的一个磁盘块的存储空间往往没有这么大,因此 InnoDB 每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小 16KB。

InnDB 在把磁盘数据读入到磁盘时会以页为基本单位,在查询数据时如果一个页中的每条数据都能助于定位数据记录的位置,这将会减少磁盘 I/O 的次数,提高查询效率。

B-Tree 结构的数据可以让系统高效的找到数据所在的磁盘块。

为了描述 B-Tree,首先定义一条数据记录为一个二元组 [key, data],key 为记录的键值,对于不同数据记录,key 是互不相同的;data 为数据记录除 key 外的数据。

那么 B-Tree 是满足下列条件的数据结构:

  1. d 为大于 1 的一个正整数,称为 B-Tree 的度。

  2. h 为一个正整数,称为 B-Tree 的高度。

  3. 每个非叶子节点由 n-1 个 key 和 n 个指针组成,其中 d<=n<=2d。

  4. 每个叶子节点最少包含一个 key 和两个指针,最多包含 2d-1 个 key 和 2d 个指针,叶节点的指针均为 null 。

  5. 所有叶节点具有相同的深度,等于树高 h。

  6. key 和指针互相间隔,节点两端是指针。

  7. 一个节点中的 key 从左到右非递减排列。

  8. 所有节点组成树结构。

  9. 每个指针要么为 null,要么指向另外一个节点。

  10. 如果某个指针在节点 node 最左边且不为 null,则其指向节点的所有 key 小于 v(key1),其中 v(key1) 为 node 的第一个 key 的值。

  11. 如果某个指针在节点 node 最右边且不为 null,则其指向节点的所有 key 大于 v(keym),其中 v(keym) 为 node 的最后一个 key 的值。

  12. 如果某个指针在节点 node 的左右相邻 key 分别是 keyi 和 keyi+1 且不为 null,则其指向节点的所有 key 小于 v(keyi+1) 且大于 v(keyi)。

B-Tree 中的每个节点根据实际情况可以包含大量的关键字信息和分支,例:

每个节点占用一个盘块的磁盘空间,一个节点上有两个升序排序的关键字和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。

两个关键词划分成的三个范围域对应三个指针指向的子树的数据的范围域。

以根节点为例,关键字为 17 和 35,P1 指针指向的子树的数据范围为小于 17,P2 指针指向的子树的数据范围为 17~35,P3 指针指向的子树的数据范围为大于 35。

模拟查找关键字 29 的过程:

  1. 根据根节点找到磁盘块 1,读入内存。【磁盘 I/O 操作第 1 次】

  2. 比较关键字 29 在区间(17,35),找到磁盘块 1 的指针 P2。

  3. 根据 P2 指针找到磁盘块 3,读入内存。【磁盘 I/O 操作第 2 次】

  4. 比较关键字 29 在区间(26,30),找到磁盘块 3 的指针 P2。

  5. 根据 P2 指针找到磁盘块 8,读入内存。【磁盘 I/O 操作第 3 次】

  6. 在磁盘块 8 中的关键字列表中找到关键字 29。

MySQL 的 InnoDB 存储引擎在设计时是将根节点常驻内存的,因此力求达到树的深度不超过 3,也就是说 I/O 不需要超过 3 次。

分析上面过程,发现需要 3 次磁盘 I/O 操作,和 3 次内存查找操作。由于内存中的关键字是一个有序表结构,可以利用二分法查找提高效率。

而 3 次磁盘 I/O 操作是影响整个 B-Tree 查找效率的决定因素。

B-Tree 相对于 AVLTree 缩减了节点个数,使每次磁盘 I/O 取到内存的数据都发挥了作用,从而提高了查询效率。

B+Tree 是在 B-Tree 基础上的一种优化,使其更适合实现外存储索引结构,InnoDB 存储引擎就是用 B+Tree 实现其索引结构。

在 B-Tree 中,每个节点中有 key,也有 data,而每一个页的存储空间是有限的,如果 data 数据较大时将会导致每个节点(即一个页)能存储的 key 的数量很小。

当存储的数据量很大时同样会导致 B-Tree 的深度较大,增大查询时的磁盘 I/O 次数,进而影响查询效率。

在 B+Tree 中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储 key 值信息,这样可以大大加大每个节点存储的 key 值数量,降低 B+Tree 的高度。

B+Tree 在 B-Tree 的基础上有两点变化:

  1. 数据是存在叶子节点中的;

  2. 数据节点之间是有指针指向的。

由于 B+Tree 的非叶子节点只存储键值信息,假设每个磁盘块能存储 4 个键值及指针信息,则变成 B+Tree 后其结构如下图所示:

通常在 B+Tree 上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有叶子节点(即数据节点)之间是一种链式环结构。

因此可以对 B+Tree 进行两种查找运算:一种是对于主键的范围查找和分页查找,另一种是从根节点开始,进行随机查找。

8. Myisam 中的 B+Tree

Myisam 引擎也是采用的 B+Tree 结构来作为索引结构。

由于 Myisam 中的索引和数据分别存放在不同的文件,所以在索引树中的叶子节点中存的数据是该索引对应的数据记录的地址,由于数据与索引不在一起,所以 Myisam 是非聚簇索引。

9. InnoDB 中的 B+Tree

InnoDB 是以 ID 为索引的数据存储。

采用 InnoDB 引擎的数据存储文件有两个,一个定义文件,一个是数据文件。

InnoDB 通过 B+Tree 结构对 ID 建索引,然后在叶子节点中存储记录。

若建索引的字段不是主键 ID,则对该字段建索引,然后在叶子节点中存储的是该记录的主键,然后通过主键索引找到对应的记录。

MySQL 的相关优化

1. MySQL 性能优化:组成、表的设计

  1. 开启查询缓存。避免某些 SQL 函数直接在 SQL 语句中使用,从而导致 Mysql 缓存失效。

  2. 避免画蛇添足。目的是什么就取什么,例如某个逻辑是只需要判断是否存在女性,若是查到了一条即可,勿要全部都查一遍,此时要善用 limit。

  3. 建合适的索引。所以要建在合适的地方,合适的对象上。经常操作 / 比较 / 判断的字段应该建索引。

  4. 字段大小合宜。字段的取值是有限而且是固定的,这种情况下可以用 enum,IP 字段可以用 unsigned int 来存储。

  5. 表的设计。垂直分割表,使得固定表与变长表分割,从而降低表的复杂度和字段的数目。

2. SQL 语句优化:避免全表扫描

  1. 建索引:一般在 where 及 order by 中涉及到的列上建索引,尽量不要对可以重复的字段建索引。

  2. 尽量避免在 where 中使用 !(<>)或 or,也不要进行 null 值判断。

  3. 尽量避免在 where 中对字段进行函数操作、表达式操作。

  4. 尽量避免使用 like- %,在此种情况下可以进行全文检索。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值