【MySQL笔记】正确的理解MySQL的索引机制以及内部实现(二)

本文详细阐述了MySQL索引机制,包括B+树索引原理、聚簇与非聚簇索引的区别,以及InnoDB与MyISAM引擎下的索引实现。通过实例展示了不同索引类型的特点与应用场景。

正确的理解MySQL的索引机制以及内部实现(二)


如果觉得对你有帮助,能否点个赞或关个注,以示鼓励笔者呢?!博客目录 | 先点这里

因为数据库索引的知识点比较多,而且感觉比较复杂和混乱!所以为了让文章更加的清晰,最终在按原目录结构写了三分之二的时候,还是决定分为两个部分分开去描述(虽然还是有很多地方没有去解释)


  • 前提概要
    • 基础数据结构
    • B树和B+树
  • 索引的一些概念
    • 主键索引和辅助键索引
    • 聚簇索引与非聚簇索引
    • 稠密索引和稀疏索引
    • 覆盖索引
  • InnoDB和MyISAM下的索引
    • InnoDB下的B+Tree索引
    • MyISAM下的B+Tree索引
    • 物理空间角度理解不同引擎下的数据存储
    • InnoDB、MyISAM下索引实现的区别和优缺点
    • 关于聚簇索引容易混淆的小贴士
  • 索引的其他底层实现
    • 哈希索引和BitMap索引
    • 倒排索引
  • 索引名词混乱的现状
    • 对于索引名词混乱的个人感受
    • 容易混淆的索引名词概念

前提概要


基础数据结构

在学习MySQL的索引之前,我们很有必要先知道一个数据结构知识。

可以说,如果不知道这三个数据结构的情况下,硬啃MySQL索引是很吃力的,也不好理解。

因为一篇博客的篇幅有限,我也不想写成两三万字的大长文,所以有需要的朋友,可以从上面的子链看看这三个数据结点的简介和概念再回到本文继续浏览


B树,B+树

毕竟B类树是构造MySQL数据库索引的底层实现(准确的说是B+树),所以本文还是要略带的介绍一下的。

什么是B树?

B树,又名B-树(B减树)。它是一棵多路平衡多路查找树。它具有一些索引结构的特性

  • 一个结点可以存储多个数据
  • 一个结点可以有多个孩子
  • 自平衡,所有叶子结点都处于同一个层次

总之,使用B树作为索引的存储结构,可以大幅的降低树的高度,保持一棵"矮胖树"的特性, 降低磁盘IO操作,提高数据库查询性能
在这里插入图片描述
什么是B+树?

那什么是一棵B+树呢?B+树说白了就是B树的变种,也是一棵平衡多路查找树,但分别结合了B树和索引顺序访问的优势,更适合成为数据库索引的底层实现

  • 所有非叶子结点只作为中间结点,存放指针地址,不存放直接的数据,所有数据存放在叶子结点上
  • 叶子结点中的所有数据都带有指向上一个,下一个数据的指针,实际双向链表结构,可以实现双向顺序访问

总而言之就是,B+树综合了B树的优点,还带有顺序索引的功能,更加的牛逼
在这里插入图片描述

B+树为什么替换了B树称为MySQL索引的底层实现?

  • B+树的磁盘读写代价更低
    因为B+树的中间结点存储的都是索引数据,仅仅是一个地址,并非直接的数据,所以同一个结点中(同一个磁盘页大小),B+树可容纳的关键字数会比B树更多(因为一个简单的地址几乎肯定小于一个直接的数据)。所以同样的数据量下,B+树会比B树更加“矮胖”,树高更小,所以查询时需要的IO次数就更少
  • B+树的查询效率更加稳定
    因为B+树的所有元素都存储在叶子结点中,而叶子结点都属于同一层级,每一个B+树查询都是从根结点遍历到叶子结点的过程,所以不管查询什么,时间复杂度相比B树查询都更加的稳定和近似。
  • B+树更有利对数据的扫描
    B树中虽然解决了查询的效率,但是如果需要查询一串相邻的数值,有可能需要回溯来回扫描或是从根结点多次中序遍历。而B+树的所有元素都存储叶子结点,每个叶子结点都有指向下一个结点的指针,直接线性遍历即可。同样B+树也更加的利于做范围查询

如果想要知道数据库索引的底层实现是怎么从二叉搜索树->平衡二叉搜索树->B树->B+树的演进过程的也可以看这篇文章初入数据结构中的B类树(B Tree , B+ Tree)


索引的一些概念


主键索引和辅助键索引

(一)主键索引(Primary Index)

  • 主键索引(primary index)
    主键索引又称主索引
    以表的主键(primary key)创建的索引树,我们就称其为该表的主键索引

(二)辅助键索引(Secondary Index)

  • 辅助键索引(secondary index)
    辅助键索引,又称辅助索引次级索引二级索引
    辅助索引以表的非主键的字段创建的索引树,我们就称其为该表的辅助键索引

简而言之,如果将一张表的所有字段都单独建立一个索引,那么除了以主键生成的索引外,其他都属于辅助键索引。 其实辅助键索引更常叫辅助索引,只是我为了对应主键索引,还是叫辅助键索引能更让人容易理解,不容易混乱。


聚簇索引和非聚簇索引

聚簇 - @百度百科

  • 聚簇是为了提高某个属性(或属性组)的查询速度,把这个或这些属性(称为聚簇码)上具有相同值的元组集中存放在连续的物理块。

(一)聚簇索引(Clustered Index)

什么是聚簇索引?

  • 聚簇索引又称聚集索引。我们将根据键值对数据库表中的数据进行排序存储,并将相关的信息聚簇在一起索引就叫聚簇索引(该顺序是物理上连续的存储空间的顺序)
  • 针对MySQL而言,聚簇索引只存在于InnoDB中,再具体些,如果有主键,一般指代的是InnoDB每个表的主键索引

聚簇索引的特性

  • 聚簇索引定义了数据存储在表中的顺序,该表的数据有且仅以一种方式排序。因此,每个表只能有一个聚簇索引。在RDBMS中,在存在主键的情况下,主键索引就是该聚簇索引

  • 聚簇索引其中一个大特征就是将索引和数据存储在同一个文件中,既叶子结点不仅保存键的信息,还保存了位于同一行其他列的信息,简而言之,聚簇索引的叶子结点保存的是一个完整行记录数据

  • 同时我们也能知道聚簇索引是一种有序索引,它的具体实现可以是稠密索引,也可以是稀疏索引

在这里插入图片描述
那些索引属于聚簇索引?

  • InnoDB和MyISAM之间,只有InnoDB支持聚簇索引
  • 若一张表存在主键,则以该主键列生聚簇索引树
  • 若一张表没有主键,则MySQL会找到该表的第一个唯一非空列的索引作为聚簇索引
  • 如以上条件皆不满足,InnoDB会在内部生成一个名为GEN_CLUST_INDEX隐式聚簇索引。该索引是基于一个名为DB_ROW_ID的隐藏字段,通常称之隐式主键。

为什么InnoDB存储引擎一定要有聚簇索引呢?

  • 因为如果我们的SQL条件是一个非主键列的数据,那么在底层索引查询中,很可能需要跨树查询,既两次查询。
  • 既InnoDB的辅助键索引的叶子结点并不存储行数据,而条件值对应的该主键值。然后我们需要根据辅助键索引查询到的主键值,再去聚簇索引中查询所以非主键索引包含两次查找,一次是查找次级索引自身,然后能再查找主键

(二)非聚簇索引(Non- Clustered Index)

什么是非聚簇索引?

  • 非聚簇索引将数据存储在一个位置,将索引存储在另一个位置,索引包含指向该数据位置的指针。这样的一个索引就是非聚簇索引,一个表中可以包含多个非聚簇索引

非聚簇索引的特征

  • 非聚簇索引是一个与聚簇索引想向的概念。针对MySQL而言,可以说InnoDB的辅助键索引,以及MyISAM的主、辅索引都是非聚簇索引
  • 非聚簇索引只存储键与指针,不存储数据,所以非聚簇索引的叶子结点仅保存数据的地址(MyISAM)或是其主键信息(InnoDB)。
  • 使用非聚簇索引进行查询,最终会定位到叶子结点,得到数据地址或主键信息,。然后还要根据获得的地址或主键信息进一步定位到数据,通常作为中间人的作用。
    在这里插入图片描述

那些索引属于非聚簇索引

  • 说白了,InnoDB
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值