mysql底层数据结构(微风正好不骄不躁是什么意思)
本篇文章给大家谈谈mysql底层数据结构,以及微风正好不骄不躁是什么意思对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
B+树作为Mysql索引结构的优点
面试时候经常会被问到mysql的索引结构,B+树相较二叉树,红黑树的优势等问题,接下来就分析下这些问题。
首先,让我们先看一张图:
从图中可以看到,我们为 user 表(用户信息表)建立了一个二叉查找树的索引。
图中的圆为二叉查找树的节点,节点中存储了键(key)和数据(data)。键对应 user 表中的 id,数据对应 user 表中的行数据。
二叉查找树的特点就是任何节点的左子节点的键值都小于当前节点的键值,右子节点的键值都大于当前节点的键值。顶端的节点我们称为根节点,没有子节点的节点我们称之为叶节点。
如果我们需要查找 id=12 的用户信息,利用我们创建的二叉查找树索引,查找流程如下:
利用二叉查找树我们只需要 3 次即可找到匹配的数据。如果在表中一条条的查找的话,我们需要 6 次才能找到。
上面我们讲解了利用二叉查找树可以快速的找到数据。但是,如果上面的二叉查找树是这样的构造:
这个时候可以看到我们的二叉查找树变成了一个链表。如果我们需要查找 id=17 的用户信息,我们需要查找 7 次,也就相当于全表扫描了。 导致这个现象的原因其实是二叉查找树变得不平衡了,也就是高度太高了,从而导致查找效率的不稳定。为了解决这个问题,我们需要保证二叉查找树一直保持平衡,就需要用到平衡二叉树了。 平衡二叉树又称 AVL 树,在满足二叉查找树特性的基础上,要求每个节点的左右子树的高度差不能超过 1。
下面是平衡二叉树和非平衡二叉树的对比:
由平衡二叉树的构造我们可以发现第一张图中的二叉树其实就是一棵平衡二叉树。
平衡二叉树保证了树的构造是平衡的,当我们插入或删除数据导致不满足平衡二叉树不平衡时,平衡二叉树会进行调整树上的悉尘节点来保持平衡。具体的调整方式这里就不介绍了。平衡二叉树相比于二叉查找树来说,查找效率更稳定,总体的查找速度也更快。
因为内存的易失性。一般情况下,我们都会选择将 user 表中的数据和索引存储在磁盘这种外围设备中。但是和内存相比,从磁盘中读取数据的速度会慢上百倍千倍甚至万倍,所以,我们应当尽量减少从磁盘中读取数据的次数。另外,从磁盘中读取数据时,都是按照磁盘块来读取的,并不是一条一条的读。如果我们能把尽量多的数据放进磁盘块中,那一次磁盘读取操作就会读取更多数据,那我们查找数据的时间也会大幅度降低。如果我们用树这种数据结构作为索引的数据结构,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块。我们都知道平衡二叉树可是每个节点只存储一个键值和数据的。那说明什么?说明每个磁盘块仅仅存储一个键值和数据!那如果我们要存储海量的数据呢?
可以想象到二叉树的节点将会非常多,高度也会极其高,我们查找数据时也会进行很多次磁盘 IO,我们查找数据的效率将会极低睁答禅!
为了解决平衡二叉树的这个弊端,我们应该寻找一种单个节点可以存储多个键值和数据的平衡树。也就是我们接下来要说的 B 树。
B 树(Balance Tree)即为平衡树的举并意思,下图即是一棵 B 树:
图中的 p 节点为指向子节点的指针,二叉查找树和平衡二叉树其实也有,因为图的美观性,被省略了。
图中的每个节点称为页,页就是我们上面说的磁盘块,在 MySQL 中数据读取的基本单位都是页,所以我们这里叫做页更符合 MySQL 中索引的底层数据结构。
从上图可以看出,B 树相对于平衡二叉树,每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子节点,子节点的个数一般称为阶,上述图中的 B 树为 3 阶 B 树,高度也会很低。
基于这个特性,B 树查找数据读取磁盘的次数将会很少,数据的查找效率也会比平衡二叉树高很多。
假如我们要查找 id=28 的用户信息,那么我们在上图 B 树中查找的流程如下:
B+ 树是对 B 树的进一步优化。让我们先来看下 B+ 树的结构图:
根据上图我们来看下 B+ 树和 B 树有什么不同:
通过上图可以看到,在 InnoDB 中,我们通过数据页之间通过双向链表连接以及叶子节点中数据之间通过单向链表连接的方式可以找到表中所有的数据。
MyISAM 中的 B+ 树索引实现与 InnoDB 中的略有不同。在 MyISAM 中,B+ 树索引的叶子节点并不存储数据,而是存储数据的文件地址。
摘自:
mysql索引采用什么数据结构
文就是对这两种数据结构做简轮册单的介绍。
1. B-Tree
B-Tree不是“B减树”,而是“B树”。
这里参考了严蔚敏《数据结构》对B-Tree的定义:
一棵m阶的B-Tree,或者为空树,或者满足下列特性:
1.树中每个结点至多有m棵子树;
2.若根结点不是叶子结点,则至少有两棵子树;
3.除根节点之外的所有非终端结点至少有[m/2]棵子树;
4.所有非终端结点中包含下列信息数据:
(n,A0,K1,A1,K2,A2……Kn,An)
其中,n为关键字的数目,K(i)为关键字,且K(i) K(i+1), Ai为指向子树根结点的指针,且指针A(i-1)所指子树中所有结点的枯桐迹关键字均小于Ki,Ai所指子树中所有结点的关键字均大于Ki;
5.所有叶子结点都出现在同一层次上;
下面通过一个例子解释一下B-Tree的查找过程。
这是一棵4阶的B-Tree,深度为4。
假如在该图中查找关键字47,首先从根结点开始,根据根结点指针t找到*a结点,因为47大于 *a 结点的关键字35,所以会去A1指针指向的 *c结点继续寻找,因为 *c的关键字 43 要查找的47 *c结点的没并关键字78,所以去 *c结点A1指针指向的 *g结点去寻找,结果在 *g结点中找到了关键字47,查找成功。
2. B+Tree
不同的存储引擎可能使用不同的数据结构存储,InnoDB使用的是B+Tree;那什么是B+Tree呢?
B+Tree是应文件系统所需而出的一种B-Tree的变型树,一棵m阶的B+树和m阶的B-树的差异在于:
1.有n棵子树的结点中含有n个关键字;
2.所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字的记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接;
3.所有的非终端结点可以看成是索引部分,结点中仅含有其子树(根结点)中的最大(或最小)关键字;
还是通过一个例子来说明。
这个例子中,所有非终端结点仅含有子树中最大的关键字。
因为叶子节点本身依据关键字的大小自小而大顺序链接,所以可以从最小关键字起顺序查找。也可以从根结点开始,进行随机查找。
在B+树中随机差找和在B-树中类似,以上图为例。假设要查找关键字51,现在根节点中比较,发现5159,因为这里使用的是非终端结点的关键字是子树中最大的关键字,所以进入最大值为59的子结点(15\44\59)中查找,同理,因为445159,所以进入P3指向的结点(51\59)中查找,然后命中关键字51,因为此结点(51\59)是叶子结点,所以查找终止,该结点包含指向数据的指针。
3.索引如何在B+Tree中组织数据存储
假设有如下表:
对于表中的每一行数据,索引中包含了last_name、first_name和dob列的值,下图展示索引是如何组织数据存储的:
索引对多个值进行排序的依据是定义索引时列的顺序。
(Allen Cuba 1960-01-01)结点左侧的指针指向[?,Allen Cuba 1960-01-01)的叶子页,(Allen Cuba 1960-01-01)和(Astaire,Angelina,1980-03-04)之间的指针指向[Allen Cuba 1960-01-01,Astaire Angelina 1980-03-04)的叶子页,以此类推。总之,每个指针指向的结点中的最小值就是该指针左侧的的值。
这种存储结构也说明了在定义多个列组成的多列索引中,为什么需要把重复率最低的列放到最左侧,因为这会减少比较的次数,查找起来更加高效。
4.索引为什么选用B树这种数据结构?
因为使用B树查找时,所用的磁盘IO操作次数比平衡二叉树更少,效率也更高。
为什么使用B树查找所用的磁盘IO操作次数比平衡二叉树更少?
大规模数据存储中,树节点存储的元素数量是有限的(如果元素数量非常多的话,查找就退化成节点内部的线性查找了),这样导致二叉查找树结构由于树的高度过大而造成磁盘I/O读写过于频繁,进而导致查询效率低下。那么我们就需要减少树的高度以提高查找效率。而平衡多路查找树结构B树就满足这样的要求。B树的各种操作能使B树保持较低的高度,从而达到有效减少磁盘IO操作次数。
[img]Mysql联合索引的最左前缀原则以及b+tree
覆盖索引,这一点是最重要的,重所周知非主键旦磨庆索引会先查到主键索引的值再从主键索引上拿到想要的值,这样多一次查询索引下推。但是覆盖索引可以直接在非主键索引上拿到相应的值,减少一次查询。
在一张大表中 如果有 (a,b,c)联合索引就等于同时加上了 (a) (ab) (abc) 三个索引 减少了存储上的一部分的开销和操作开销
梯度漏斗,比如 select *from t where a = 1 and b = 2 and c = 3; 就等于在满足 a = 1 的一部分数据中过滤掉b = 2 的 再从 a = 1 and b = 2 过滤掉 c = 3 的,越多查询越高效。
即最左优先,在检索数据时从联合索引的最左边开始匹配,类似于给(a,b,c)这三个字段加上联合索引就等于同时加上了 (a) (ab) (abc) 这三种组合的查询优化
举个栗子:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(25),
`sex` varchar(25) ,
`city` varchar(25) ,
PRIMARY KEY (`id`) USING BTREE,
INDEX `name`(`name`, `sex`, `city`) USING BTREE
)
EXPLAIN select *from`user` where sex='';
这样是无法触发联合索引的,因为不符合最左原则,没有命中(a) (ab) (abc) 这种组合
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+| 1 | SIMPLE | user | NULL | index | NULL | name | 309 | NULL | 3 | 33.33 | Using where; Using index |+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+1 rowinset (0.02 sec)
另外使用执行计划一定要看结果,只有possible_keys有值的情况下才是命中索引
查询条件要符合最左原则才能使用到索引
注意: where条件的顺序是否会影响索引的命中,就模握是本来(ab)的组合,故意写where语句时写成(ba),答案是没有影响,只要遵循了索引的最左原则即可,至少在mysql5.7测试没有问题。
最后,谈谈索引的底层数据结构b+tree
我们知道BTREE 每个节点都是一个二元数组: [key, data],所有节点都可以存储数据。key为索引key,data为除key之外的数游肆据。
查找算法:首先从根节点进行二分查找,如果找到则返回对应节点的data,否则对相应区间的指针指向的节点递归进行查找,直到找到节点或未找到节点返回空指针
B+Tree有以下不同点:非叶子节点不存储data,只存储索引key;只有叶子节点才存储data,而Mysql中B+Tree:在经典B+Tree的基础上进行了优化,增加了顺序访问指针。在B+Tree的每个叶子节点增加一个指向相邻叶子节点的指针,就形成了带有顺序访问指针的B+Tree。这样就提高了区间访问性能:请见下图,如果要查询key为从18到49的所有数据记录,当找到18后,只需顺着节点和指针顺序遍历即可
依据来源(官网的文档 ):
mysql数据库的优化方法?
我们都知道,服务器数据库的开发一般都是通过java或者是PHP语言来编程实现的,而为了提高我们数据库的运行速度和效率,数据库优化也成为了我们每日的工作重点,今天,昌平IT培训就一起来了解一下mysql服务器数据库的优化方法。
为什么磨局要了解索引
真实案例
案例一:大学有段时间学习爬虫,爬取了知乎300w用户答题数据,存储到mysql数据中。那时不了解索引,一条简单的“根据用户名搜索全部回答的sql“需要执行半分钟左右,完全满足不了正常的使用。
案例二:近线上应用的数据库频频出现多条慢sql风险提示,而工作以来,对数据库优化方面所知甚少。例如一个用户数据页面需要执行很多次数据库查询,性能很慢,通过增加超时时间勉强可以访问,但是性能上需要优化。
索引的优点
合适的索引,可以大大减小mysql服务器扫描的数据量,避免内存排序和临时表,提高兄稿应用程序的查询性能。
索引的类型
mysql数据中有多种索引类型,primarykey,unique,normal,但瞎尘让底层存储的数据结构都是BTREE;有些存储引擎还提供hash索引,全文索引。
BTREE是常见的优化要面对的索引结构,都是基于BTREE的讨论。
B-TREE
查询数据简单暴力的方式是遍历所有记录;如果数据不重复,就可以通过组织成一颗排序二叉树,通过二分查找算法来查询,大大提高查询性能。而BTREE是一种更强大的排序树,支持多个分支,高度更低,数据的插入、删除、更新更快。
现代数据库的索引文件和文件系统的文件块都被组织成BTREE。
btree的每个节点都包含有key,data和只想子节点指针。
btree有度的概念d=1。假设btree的度为d,则每个内部节点可以有n=[d+1,2d+1)个key,n+1个子节点指针。树的大高度为h=Logb[(N+1)/2]。
索引和文件系统中,B-TREE的节点常设计成接近一个内存页大小(也是磁盘扇区大小),且树的度非常大。这样磁盘I/O的次数,就等于树的高度h。假设b=100,一百万个节点的树,h将只有3层。即,只有3次磁盘I/O就可以查找完毕,性能非常高。
索引查询
建立索引后,合适的查询语句才能大发挥索引的优势。
另外,由于查询优化器可以解析客户端的sql语句,会调整sql的查询语句的条件顺序去匹配合适的索引。
关于mysql底层数据结构和微风正好不骄不躁是什么意思的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。