精华内容
下载资源
问答
  • mysql索引底层结构B树和B+树

    千次阅读 2019-08-21 18:00:26
    目前大多数数据库系统及文件系统都采用 B-Tree 或其变种 B+Tree 作为索引结构。B+ 树中的 B (balance)代表平衡,而不是二叉。B+ 树是从最早的平衡二叉树演化而来的。B+ 树是由二叉查找树、平衡二叉树(AVLTree)和...

    1.为什么要用B+Tree实现

    目前大多数数据库系统及文件系统都采用 B-Tree 或其变种 B+Tree 作为索引结构。B+ 树中的 B (balance)代表平衡,而不是二叉。B+ 树是从最早的平衡二叉树演化而来的。B+ 树是由二叉查找树、平衡二叉树(AVLTree)和平衡多路查找树(B-Tree)逐步优化而来。

    二叉查找树:左子树的键值小于根的键值,右子树的键值大于根的键值。
    AVL 树:平衡二叉树(AVL 树)在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为 1,但不是红黑树。
    平衡多路查找树(B-Tree):为磁盘等外存储设备设计的一种平衡查找树。
    那么纠结该如何选型呢?

    索引的标准:IO渐进复杂度,说白了就是推演过程(每个节点都是1次IO),B+树是为磁盘及其他存储辅助设备而设计一种平衡查找树(不是二叉树),所有记录的节点按大小顺序存放在同一层的叶节点中,各叶节点用指针进行连接。

    InnoDB 存储引擎使用页作为数据读取单位,页是其磁盘管理的最小单位,默认 page 大小是 16k。系统的一个磁盘块的存储空间往往没有这么大,因此 InnoDB 每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小 16KB。在查询数据时如果一个页中的每条数据都能助于定位数据记录的位置,这将会减少磁盘 I/O 的次数,提高查询效率。

    3.1 B-Tree
    B-树是一种多路自平衡的搜索树 它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点。B-Tree 相对于 AVLTree 缩减了节点个数,使每次磁盘 I/O 取到内存的数据都发挥了作用,从而提高了查询效率。

    注:B-Tree就是我们常说的B树,一定不要读成B减树,否则就很丢人了

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

    所有键值分布在整颗树中
    搜索有可能在非叶子结点结束,在关键字全集内做一次查找,性能逼近二分查找
    每个节点最多拥有m个子树
    根节点至少有2个子树
    分支节点至少拥有m/2颗子树(除根节点和叶子节点外都是分支节点)
    所有叶子节点都在同一层、每个节点最多可以有m-1个key,并且以升序排列

    在这里插入图片描述
    每个节点占用一个磁盘块,一个节点上有两个升序排序的关键字和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。两个关键词划分成的三个范围域对应三个指针指向的子树的数据的范围域。以根节点为例,关键字为 17 和 35,P1 指针指向的子树的数据范围为小于 17,P2 指针指向的子树的数据范围为 17~35,P3 指针指向的子树的数据范围为大于 35。

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

    根据根节点找到磁盘块 1,读入内存。【磁盘 I/O 操作第 1 次】
    比较关键字 29 在区间(17,35),找到磁盘块 1 的指针 P2。
    根据 P2 指针找到磁盘块 3,读入内存。【磁盘 I/O 操作第 2 次】
    比较关键字 29 在区间(26,30),找到磁盘块 3 的指针 P2。
    根据 P2 指针找到磁盘块 8,读入内存。【磁盘 I/O 操作第 3 次】
    在磁盘块 8 中的关键字列表中找到关键字 29。
    分析上面过程,发现需要 3 次磁盘 I/O 操作,和 3 次内存查找操作。由于内存中的关键字是一个有序表结构,可以利用二分法查找提高效率。而 3 次磁盘 I/O 操作是影响整个 B-Tree 查找效率的决定因素。

    但同时B-Tree也存在问题:

    每个节点中有key,也有data,而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的 key 的数量很小。
    当存储的数据量很大时同样会导致 B-Tree 的深度较大,增大查询时的磁盘 I/O 次数,进而影响查询效率
    3.2 B+Tree
    B+Tree 是在 B-Tree 基础上的一种优化,InnoDB 存储引擎就是用 B+Tree 实现其索引结构。它带来的变化点:
    在这里插入图片描述
    B+树每个节点可以包含更多的节点,这样做有两个原因,一个是降低树的高度。另外一个是将数据范围变为多个区间,区间越多,数据检索越快
    非叶子节点存储key,叶子节点存储key和数据
    叶子节点两两指针相互链接(符合磁盘的预读特性),顺序查询性能更高
    注:MySQL 的 InnoDB 存储引擎在设计时是将根节点常驻内存的,因此力求达到树的深度不超过 3,也就是说 I/O 不需要超过 3 次。

    通常在B+Tree上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有叶子节点(即数据节点)之间是一种链式环结构。因此可以对 B+Tree 进行两种查找运算:一种是对于主键的范围查找和分页查找,另一种是从根节点开始,进行随机查找。

    3.3 B-树和B+树的区别
    B+树内节点不存储数据,所有数据存储在叶节点导致查询时间复杂度固定为 log n
    B-树查询时间复杂度不固定,与 key 在树中的位置有关,最好为O(1)
    B+树叶节点两两相连可大大增加区间访问性,可使用在范围查询等
    B-树每个节点 key 和 data 在一起,则无法区间查找
    B+树更适合外部存储(存储磁盘数据)。由于内节点无 data 域,每个节点能索引的范围更大更精确。

    **

    4.Mysql索引是如何实现的

    **
    4.1 InnoDB 中的 B+Tree
    InnoDB 是通过 B+Tree 结构对 ID 建索引,然后在叶子节点中存储记录。采用 InnoDB 引擎的数据存储文件有两个,一个定义文件,一个是数据文件。

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

    在这里插入图片描述

    4.2 Myisam 中的 B+Tree
    Myisam 引擎也是采用的 B+Tree 结构来作为索引结构。由于 Myisam 中的索引和数据分别存放在不同的文件,所以在索引树中的叶子节点中存的数据是该索引对应的数据记录的地址,由于数据与索引不在一起,所以 Myisam 是非聚簇索引。

    在这里插入图片描述

    展开全文
  • MySQL索引底层结构为什么选择B+树

    千次阅读 2019-03-31 10:51:24
    MySQL官网介绍:索引是帮助mysql高效获取数据的排好序的数据结构。简而言之,索引本质是一种优化查询的数据结构。 比较如下一些数据结构索引,就可以发现其中的缘由。 1.Hash索引 Hash索引把数据以hash形式组织...

    MySQL官网介绍:索引是帮助mysql高效获取数据的排好序的数据结构。简而言之,索引本质是一种优化查询的数据结构。
    比较如下一些数据结构的索引,就可以发现其中的缘由。
    1.Hash索引
    Hash索引把数据以hash形式组织起来,因此查找某一条记录的时候,速度非常快。同时.hash算法的索引有个缺点,因为它不是按照大小排序的。所以,它无法按照范围进行查找。
    在这里插入图片描述
    2.二叉树结构索引
    二叉树的定义:
    1.任意节点左子树不为空,则左子树的值均小于根节点的值;
    2.任意节点右子树不为空,则右子树的值均大于于根节点的值;
    3.任意节点的左右子树也分别是二叉查找树;
    4.没有键值相等的节点;
    如图:
    在这里插入图片描述
    很显然,这种结构的树查询最坏的情况就会像一个线性结构,这种结构对I/O的操作次数增加,若想减少查询次数。可以看下最好的状态,平衡二叉树。
    3.平衡二叉树索引(AVL)
    AVL的必要条件如下:
    1.必须是二叉查找树
    2,每个节点的左子树和右子树的高度差至多为1
    在这里插入图片描述
    左边二叉树的节点45左子树高度2,右子树高度0,左右子树高度差为2-0=2,不满足条件二;
    右边二叉树的节点均满足左右子树高度差至多为1,同时它满足二叉搜索树的要求,因此它是一棵平衡二叉树。
    进一步研究平衡二叉树,如果要查询10,按照AVL的查找方法,则需要对I/0进行四次操作
    在这里插入图片描述
    而同等数据量的情况下,B树和B+树的查找次数要少。
    4.B树的索引结构
    1、根节点至少有两个孩子
    2、每个非根节点至少有M/2(上取整)个孩子,至多有M个孩子。
    3、每个非根节点至少有M/2-1(上取整)个关键字,至多有M-1个关键字。并以升序排列;key[i]和key[i+1]之间的孩子节点的值介于key[i]和key[i+1]之间。
    4、所有的叶子结点都位于同一层。
    用B树的结构,查找的话,只需要对I/O进行3次操作
    在这里插入图片描述
    5.B+树
    B+树是B树的一个升级版。
    新增特性
    叶子节点冗余了所有的非叶子节点的key
    每个叶子节点增加了一个指向相龄叶子节点的指针
    在这里插入图片描述
    这里可以看到,虽然这里查找10,也只是和B树一样需要操作3次I/O。但是B+树将所有的非叶子节点的索引都存放在叶子节点,并且还增加了顺序访问的指针,每个叶子节点都有指向相邻叶子节点的指针,这样当其他操作或者大量数据查询时,可以大大减少对I/O磁盘的读取操作。
    综上:减少对磁盘的I/O操作,所以选B+树更合适作为数据库的索引。

    展开全文
  • MySQL索引底层数据结构索引到底是什么联合索引结构MyISAM索引文件和数据文件是分离的主键索引普通索引InnoDB索引实现主键索引普通索引 索引到底是什么 索引是帮助MySQL高效获取数据的 排好序 的 数据结构 索引存储...

    索引到底是什么

    • 索引是帮助MySQL高效获取数据的 排好序数据结构
    • 索引存储在文件,MySQL使用的数据结构为 B+Tree
      在这里插入图片描述

    数据结构教学网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
    B-Tree 数据结构:https://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw==&mid=2653190965&idx=1&sn=53f78fa037386f85531832cd5322d2a0&chksm=8c9909efbbee80f90512f0c36356c31cc74c388c46388dc2317d43c8f8597298f233ca9c29e9&scene=21#wechat_redirect
    B+Tree 数据结构:https://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw==&mid=2653191027&idx=1&sn=4ba22e3ec8bd149f69fc0aba72e4347e&chksm=8c9909a9bbee80bfa1d8497ff0525df130414c1731b5aa5287bf16ea1cf86c8d8e6f20782184&scene=21#wechat_redirect

    联合索引结构

    在这里插入图片描述

    聚集索引和非聚集索引

    根本区别

    • 数据的物理存放顺序与索引顺序是否一致

    MyISAM和InnoDB的索引

    • MyISAM的B+Tree的叶子节点上的data,并不是数据本身,而是数据存放的地址。主索引和辅助索引没啥区别,只是主索引中的key一定得是唯一的。这里的索引都是非聚集索引。

    • InnoDB的数据文件本身就是索引文件,B+Tree的叶子节点上的data就是数据本身,key为主键,这是聚集索引。非聚集索引,叶子节点上的data是物理地址(所以聚集索引的key,不能过长)。为什么存放的主键,而不是记录所在地址呢,理由相当简单,因为记录所在地址并不能保证一定不会变,但主键可以保证。

    • 至于为什么主键通常建议使用自增id呢?

    MyISAM索引文件和数据文件是分离的(非聚集)

    主键索引

    在这里插入图片描述

    普通索引

    在这里插入图片描述

    InnoDB索引实现(聚集)

    主键索引

    在这里插入图片描述

    普通索引

    在这里插入图片描述

    1. 数据文件本身就是按B+Tree组织的一个索引结构文件
    2. 索引-叶子节点包含了完整的数据记录
    3. 为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
    4. 为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)
    展开全文
  • MySQL - 剖析MySQL索引底层数据结构

    千次阅读 2020-07-18 16:51:14
    文章目录Pre Pre 什么是索引? 通俗的说就是为了提高效率专门设计的一种 排好序的数据结构。 怎么理解呢? 举个例子哈 如上数据 ,假设有个SQL select * from t where col2 = 22 ;

    在这里插入图片描述

    更多干货

    带你搞定MySQL实战,轻松对应海量业务处理及高并发需求,从容应对大场面试


    Pre

    什么是索引?

    通俗的说就是为了提高效率专门设计的一种 排好序数据结构

    怎么理解呢?

    举个例子哈

    在这里插入图片描述

    如上数据 ,假设有个SQL

    select *  from t where  col2 = 22 ;
    

    如果没有索引的话,是不是得逐行进行全表扫描,走磁盘IO…

    如果加上一个合适的索引呢?

    比如用一个二叉树

    在这里插入图片描述

    二叉树我们知道,右边的比左边大

    那执行刚才的SQL的话,第一条记录是34 ,那我们查找的是22, 是不是就只要到它的左边查找即可,因为右边的数据都比34大,肯定没有22 ,找到22 以后, 搞定 ,I/O次数是不是比刚才的全表扫描的次数少很多,那效率自然就高了。


    索引的数据结构选型

    二叉树 ?

    可以用二叉树吗? 我们知道MySQL一般都有自增主键 ,id之类的字段

    我们来演示下使用二叉树来存储这种自增的数据的话,会怎样?

    https://www.cs.usfca.edu/~galles/visualization/BST.html

    在这里插入图片描述

    那查询

    select * from t where id = 7
    

    在这里插入图片描述

    自增主键的时候 这个二叉树已经退化成链表了。。。。。

    想想,一个几百万数据量的表 ,查找某个大一点的id , 逐个查找比对 (这些数据也是存储在磁盘上的,还得从磁盘上捞啊) 这I/O 这效率可想而知吧…

    二叉树 pass ,不考虑了

    既然退化成链表了,那试试带有平衡功能的树 二叉平衡树 (红黑树)?

    自增主键, 退化为为链表


    红黑树 ?

    二叉树既然在某些情况下会退化成链表, 那如果这棵树能自动平衡呢?

    在这里插入图片描述

    这样子是不可能变成链表了,

    同样 查询

    select * from t where id = 7
    

    在这里插入图片描述

    三次磁盘I/O即可找到, 比刚才二叉树的七次是少了些哈 ,自然查找效率也比二叉树高了

    可如果数据量几百万 上千万呢?

    这棵树 得多高哇。。。

    数据量大, 树高问题

    那既然树高不好, 是不是如果可以控制树的高度(比如 3 到4层的高度,这样查询起来还能接受),让每一层能存储更多的数据,然后再分裂,这样的话数据量相乘起来,也是不少了对吧,这样就能存储更多的数据,这样会不会好一点? ----> B-Tree


    B-Tree ?

    • 叶节点具有相同的深度, 叶节点之间指针为空
    • 所有索引元素不重复
    • 节点中的数据索引从左到右递增排列

    在这里插入图片描述

    叶子节点之间的没有指针,区别于B+树。

    data存储的是数据对应的磁盘地址, k-v结构。

    我们来看下B-Tree的插入 (Max.Degree 设置为3 即 元素到了3个就分裂 )
    在这里插入图片描述

    查找一下

    在这里插入图片描述

    3次

    MySQL也没有使用B-Tree , 因为
    在这里插入图片描述

    除了存储索引以外,还存储了data(数据对应的磁盘地址) , 为了更多的存储数据,MySQL对B-Tree进行了很多改造

    由此演进出了 B+Tree ,将data部分仅保留在叶子节点上,这样的话同等的页可以存储更多而索引数据。


    B+Tree

    • 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
    • 叶子节点包含所有索引字段
    • 叶子节点用指针连接,提高区间访问的性能

    在这里插入图片描述

    数据仅存储在叶子节点, data可能是磁盘地址也可能是其他的列数据,这个和存储引擎有关系。

    叶子节点之间有指针相连。

    我们来算下 3层高的B+Tree能存储多少数据结构

    假设是BigInt类型的数据

    在这里插入图片描述

    BigInt 占 8个字节 ,同时还是用6个字节存储了它指向的数据的物理地址

    MySQL在使用innodb引擎的时候页大小默认是16K ,查询如下

    mysql> SHOW GLOBAL STATUS like 'Innodb_page_size';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | Innodb_page_size | 16384 |
    +------------------+-------+
    1 row in set (0.00 sec)
    
    mysql>
    

    假设 树高为3 , 这样的话,第一层即可以存储 16KB * 1024 / (8B + 6B) = 1170

    同样的第二层也是1170 (第二层不是叶子结点,不存储数据)

    第三层,存储数据,一般情况下一行数据的大小肯定不会超过1KB,那我们就按照1KB算吧

    3层高的B+Tree , 存储BitInt可以存储 1170 * 1170 * 16 = 2千1 百万。。。。这效率还是可以的哈

    想一想 如果是4层高的数 1170 * 1170 * 1170 * 16 = 250多亿数据。.。。。

    当然了 都是估算, 如果换成其他类型的数据,每个表的行数据的大小都是相关的,这也就是我们通常说的 MySQL的表到千万级别就要分库分表的理论依据了。

    我们看下B+Tree的插入和查找

    在这里插入图片描述

    在这里插入图片描述


    Hash表

    • 对索引的key进行一次hash计算就可以定位出数据存储的位置
    • 很多时候Hash索引要比B+ 树索引更高效
    • 仅能满足 “=”,“IN”,不支持范围查询
    • hash冲突问题

    在这里插入图片描述

    对索引字段进行hash以后, 还存储了数据对引得磁盘地址。

    一般请款下,hash 比 b+tree的效率要高 ,但工作中绝大部分还是使用的B+Tree , 因为hash对范围查找不是很友好,还要全表扫描

    为啥B+Tree 支持范围查找?

    我们知道B+Tree的叶子节点 有指针相连,从根节点找到对应的叶子节点后, 加上节点本身就是排好序的,所以范围查找就恨轻松了。

    B-Tree 没有指针相连,所以要想范围查找,还得从根节点重新找,效率肯定比B+树低 。


    搞定MySQL

    在这里插入图片描述

    展开全文
  • 深入理解MySQL索引底层数据结构与算法

    万次阅读 多人点赞 2018-10-10 11:10:58
    (五) B+Tree(MySQL索引的真正存储结构) 三. 联合索引底层存储结构 一 理解索引的特性 索引是帮助MySQL高效获取数据的排好序的数据结构 索引存储在文件里 二 索引的各种存储结构及其优缺点 在开始讲这一小节...
  • mysql 索引底层数据结构: 二叉树:如果是规律性数据,比如1,2,3.....等数据,存储容易成线性结构,数据规模太大之后,查询太慢。 红黑树(hashap的底层数据结构):存在自平衡性问题,虽然不会出现单边增长,...
  • Mysql索引底层数据结构(B树) 一.什么是B树 B - Trees是一种平衡的多叉树,称为B树(或B-树、B_树),也是数据结构中树形结构的一种。 二.什么是索引,为什么要用要索引 索引是帮助Mysql高效获取数据的排好序的数据...
  • 深入理解 MySQL 索引底层原理 Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 Mysql 整体的数据检索性能。 何为索引 ...
  • 文章目录索引的本质B-TreeB+Tree(B-Tree变种)存储引擎索引实现MyISAMInnoDB联合索引底层结构 索引的本质 索引是帮助MySQL高效获取数据的排好序的数据结构 索引数据结构 二叉树 红黑树 Hash表 B-Tree B-Tree ...
  • Mysql索引底层数据结构与算法

    千次阅读 2020-01-31 18:33:58
    目录 1. 索引概念 2. 索引结构 ...索引概念:索引是帮助MySQL高效获取数据的排好序的数据结构,更通俗的说数据库索引好比是一本书的目录,能加快数据库的查询速度 索引结构:二叉树, 红黑树, HASH, BTREE ...
  • MYSQL中索引的底层结构 首先,让我们搞清楚“树”这种数据结构。 参考文章链接: MySQL索引底层实现原理
  • 【mysql知识点整理】 --- mysql索引底层数据结构

    千次阅读 多人点赞 2020-02-28 12:34:47
    文章目录1 什么是索引 1 什么是索引 索引是帮助MySQL高效的获取数据的数据结构
  • 深入理解Mysql索引底层原理 一步一步推导出Mysql索引的底层数据结构。 Mysql作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是Mysql数据的存储形式以及索引的设计,决定了...
  • 深入理解 MySQL 索引底层的数据结构

    千次阅读 热门讨论 2021-02-27 23:04:08
    ### MySQL索引 #### 索引基础 #### 索引类型 ##### B-Tree索引 ##### 哈希索引 ##### 全文索引 #### 索引的优点 #### 高性能的索引 ##### 独立索引 ##### 多列索引 ##### 聚簇索引 ##### 覆盖索引
  • MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。我们知道,数据库查询是数据库的最主要功能之一。我们都希望查询数据的速度能尽...
  • mysql索引底层原理mysql 引擎什么是索引数据结构什么是B树B树结构图什么是B+树两者有什么不同之处mysql索引为什么用B+树了解了mysql 索引底层有什么用 mysql 引擎 MyISAM 引擎和 InnoDb引擎 用表对比: 引擎 主...
  • 深入理解 MySQL 索引底层原理 Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 Mysql 整体的数据检索性能。 何为索引 我们...
  • 这就要从索引的本质以及他的底层原理说起。 索引是什么 那索引到底是什么呢?你是不是还停留在大学学『数据库原理』时老师讲的“索引就像字典的目录”这样的概念?老师讲的没错,但没有深入去讲。 其实...
  • MYSQL索引底层的数据结构

    千次阅读 2018-07-07 16:34:24
    特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。为了避免混乱,本文将只关注于BTre...
  • Mysql索引底层及优化

    2021-04-14 15:07:18
    Mysql索引篇 最近在很多网站上看了索引的相关知识,各种说法的都有,但是又不是很全,有的概念很模糊,下面是由小编整理的Mysql索引知识点。 一.首先我们说下什么是索引,为什么要用索引 索引用于快速找出在某个列中...
  • Mysql索引底层原理分析, Mysql索引的本质 Mysql索引的底层原理 Mysql索引的实战经验 面试 问:数据库中最常见的慢查询优化方式是什么? 同学A:加索引。 问:为什么加索引能优化慢查询?同学A:…不知道同学B:因为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 54,381
精华内容 21,752
关键字:

mysql索引底层结构

mysql 订阅