mysql索引数据结构及底层的索引存储方式

相关数据结构可视化工具:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

1.二叉树

     在某种情况下,二叉树会退化成链表结构,查询的时候与全表扫描没有区别,与磁盘io次数过多导致效率低下。

2.红黑树

     红黑树相较于二叉树做了平衡操作,树的两边的高度相近,但是在数据量很大的情况下,树的高度可能过高,当查询数据位于叶子节点附近时,磁盘io次数和树的高度相关,当树高度较大时会造成查询效率低下。

3.B树

     前面两种树结构会随着数据量的增长,树的高度会不断增高,若想控制树的高度稳定在3~4层,可使用b树,红黑树的每个索引节点存储在磁盘的某个位置上,这些位置可能是随机的的,若一开始在磁盘上开辟一块较大空间,在一个数据页里存储尽可能多的索引元素,这样在相同的数据量的情况下,这种存储会让树的高度更小。

即:

即:

4.b+树

     b+树对b树做了一些优化,b树的索引节点是一个k-v结构,k存储索引值,v存储对应的行的磁盘地址,而b+树的非叶子结点不存储data,只存储索引(冗余索引),这样可以存放更多的索引,也就意味着叶子节点包含了所有索引字段。且b+树的叶子节点用指针连接,提高了区间访问,如范围查询的速度。

     当要查询等于30的这条记录时,首先会将根节点的排好序索引加载进内存,二分定位到30位于15-56之间,这之间存储的是数据页在磁盘上的地址,定位到数据页后将数据页加载进内存,以同样的逻辑定位到30位于20-49之间,定位到下一个节点的数据页的磁盘文件地址,以同样的逻辑找到30这条记录,再依据叶子节点存储的对应行的地址去粗盘上找到对应的行数据。

mysql每一个存储索引的数据页大小默认是16k(show global status like 'Innodb_page_size'),假设在一个数据页里每个索引为bigint类型(8个字节),存储的下一个索引页的地址为6字节,一个数据页存储的索引树大概为18(k)/(8+6)b=1170个元素,叶子节点data一般不会超过1kb,每个叶子节点可存储16个元素,整棵树总存储节点数为1170*1170*16个索引,大约一千多万的索引节点个数,此时数的高度为3,查找某个数据最多经过3次的磁盘io即可,千万级别的表如果走索引查询效率也是很快的。

对于myisam存储引擎,索引文件和数据文件是分离的(非聚集索引),索引及数据在磁盘上的存储方式:

  • frm文件:数据表结构信息存储。
  • myd文件:表数据文件。
  • myi文件:索引文件。

      插入数据时,在myi文件中会根据索引将列数据以b+树的结构组织存储起来,当以某个索引列为查找条件时,在myi文件中从b+树的根节点开始遍历,找到节点对应的行的磁盘文件地址,再根据地址再去myd文件中找到具体的行数据。

对于innodb存储引擎

  • ibd文件:数据表文件

      对于聚集索引(主键索引)来说,b+树组织的索引结构文件的叶子节点存储当前索引行的其他列的数据

5.Hash索引

      当对某个列建hash索引时,会对插入的列值进行一次hash运算,定位到具体的hash桶,将数据以hash结构组织起来,链表节点不仅存储当前列的值,还存储了当前索引行的磁盘文件地址。

优缺点

  • 对索引的key进行一次hash运算即可定位到具体的行地址。
  • 大多数时候比b+树索引更高效。
  • 仅能支持‘IN’和‘=’,不支持范围查询。
  • hash冲突
posted @ 2022-12-20 16:37  StudyHardWork  阅读(568)  评论(0编辑  收藏  举报