Mysql索引底层数据结构详细介绍

索引的本质

索引是帮助Mysql高效获取数据的排好序数据结构

数据结构

二叉树 红黑树 Hash表 B-Tree B+Tree

二叉树

数据库如果不建立索引,查询数据的时候会采取逐行比对的方式,去获取查询的数据,这样查询如果数据量越来越大的情况下,消耗的时间也会越来越长。

下图Col2做为索引列,获取Col2=89只需要两次就可以获取到89的索引,定位到数据,获取到。如果不采用索引,需要逐行去比对6次才能获取到。
在这里插入图片描述
Mysql底层其实不是采用的二叉树数据结构作为索引的。如果把Col1做为索引列,二叉树数据结构如下图所示,想要获取数据即使走索引也需要6次查找,对效率优化不是很大,说白了,二叉树对这种单边增长的数据列作为索引对效率的提升,没有太大的帮助。
在这里插入图片描述

红黑树

下图红黑树的数据结构,貌似解决了二叉树单边增长的问题,获取索引6只需要查询3次就可以获取到。但是这还不是最佳方案,现在的数据量不大,如果数据量达到几百万,上千万级别,红黑树的高度会越来越高,比如树的高度=18,那查询一条数据需要18次磁盘IO,效率也不是很高。
在这里插入图片描述

B-Tree

  • 叶节点具有相同的深度。
  • 所有的索引不重复。
  • 节点中的索引从左到右依次排序

在这里插入图片描述

B+Tree(B-Tree变种)

Mysql采用的数据结构

  • 非叶子节点不储存data数据,只储存索引,这样可以释放空间来存放更多的索引。
  • 叶子节点包含所有的索引字段。
  • 叶子节点用指针连接,提升区间访问性能。

查询语句:show variables like ‘innodb_page_size’
一个非叶子节点默认可以存储16384个字节,也就是16KB。打个比方一个索引占8个字节,下一个索引文件地址占6个字节。16384除以8加6等于1170,也就是一个非叶子节点大约可以存1170个索引元素。但是叶子节点需要存储data元素,分配1KB就足够用了,也就是一个叶子节点可以存16个元素。这样算的话,如果树高为3,可以储存的数据等于1170乘1170乘16等于2千多万。也就是说两千多万的数据磁盘io三次就可以获取到你想要的数据啦。
在这里插入图片描述

Hash

  • 对索引key进行一次Hash计算就能定位到数据位置。
  • Hash很多时候性能比B+Tree索引更高效。
  • 但是不支持范围查找

在这里插入图片描述

Mysql为什么选择B+Tree而不是B-Tree呢?

  • B+Tree把B-Tree非叶子节点上data元素全部挪到叶子节点上,释放了更多的空间去存储索引元素,所以2千万的数据存进来树的高度只有3,如果用B-Tree存储2千万数据,树的高度决定远远大于3
  • B+Tree叶子节点还有指针关联,范围查找比如 id>15,就会定位到15后根据指针依次获取后面数据,来提升区间访问性能。

MyISAM储存引擎索引实现(非聚集)

在这里插入图片描述

InnoDB储存引擎索引实现(聚集)

在这里插入图片描述
二级索引
二级索引data元素储存的是主键值,根据主键id再回表操作在这里插入图片描述

联合索引储存结构

在这里插入图片描述

  • 索引最左前缀原则

数据结构可视化网址:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

猜你喜欢

转载自blog.csdn.net/weixin_51049616/article/details/108795342