mysql索引树结构分析

本专栏只为作者学习记录

索引是什么?

mysql索引树结构分析_第1张图片

  1. 这里是索引的定义,简述来说索引就是在物理层面一种排好序的数据结构,顾名思义,就是将表中的数据根据特定的数据结构进行存储。

  2. 索引的使用过程 MySQL在解析查询语句时会解析到这条语句是否会走到对应的索引,再去将对应的索引文件(存储在物理内存中索引文件存放路径参考MySQL索引的存放路径以及后缀文件解析)加载到RAM中,再根据索引采用的树结构特性在根节点或叶子节点进行数据的快速查找,(例:二分查找),不同特性的索引数据结构上存储的字段多少不同(下面会讲到不同索引使用的数据结构),如果索引树索引到数据包含了查询所要的所有字段,就不用再次进行回表(下面会讲到),至此拿到数据。

  3. 索引使用的数据结构(图片演示网址)

    二叉树(Binary tree)
  • 介绍:二叉树这种数据结构的特殊性在于比叶子节点大的数据都会放在右侧,如果要索引的数据为6,就要在树结构上寻找6次。

    mysql索引树结构分析_第2张图片

    红黑树

    介绍:红黑树是一种变种二叉树在拥有二叉树的特性之上还能够对树节点 进行自动平衡,也叫做平衡二叉树。从图中可以看出索引的效率要比二叉树更高。

mysql索引树结构分析_第3张图片

Hash表
介绍:通过对放入的对象进行hash取值并进行存放,看似取数据是O(1)但也有自己的优缺点例如下hash索引一般由mysql自动维护。

优点
因为索引自身只需存储对应的哈希值,所以索引的结构十分紧凑,这也让哈希索引查找的速度非常快

缺点:

  • 不能避免读取行
  • 无法用于排序
  • 无法使用部分索引列匹配查找
  • 只支持等值查找
  • 存在Hash冲突

mysql索引树结构分析_第4张图片

B-Tree

介绍:

  • 叶节点具有相同的深度,叶子节点间互相隔开没有指针关联

  • 叶子节点和非叶子节点上的树据有序排列

  • 叶子节点和非叶子节点都携带数据(这里的可以理解为MySQL表中的一行数据 10理解为数据的id data为其他字段信息 )

  • 所有索引元素不重复

  • 节点中的数据索引从左到右递增排列

优点

  • 数据索引的排好序能够方便我们进行范围查找
  • 能够利用二分法则快速查找

缺点:

  • 根节点携带有完整数据,会在索引导致根节点储存数据量减少

  • 叶子节点上数据没有指针互相指向,在进行范围查找时效率会降低

mysql索引树结构分析_第5张图片

B+Tree
介绍:B+树正是B树的变种类型,mysql InnorDB存储引擎目前使用的也是这种数据结构,相比B树进行了改进
  • 根节点和非叶子节点只保存数据id(不同的索引类型可能保存的字段不一) 这样做的好处就是减少了根节点的非叶子节点的某个数据的大小,这样一来就能够储存更多的树节点数据。
  • 叶子节点保存所有字段
  • 叶子节点的数据间有指针连接,在查询到这个叶子节点时能够快速找到下个叶子节点的存储地址,提高了区间的访问性能

mysql索引树结构分析_第6张图片

常见索引类型介绍

  • 聚簇索引
    聚簇索引也可以叫做主键索引,聚集索引,对于聚簇两字分析我的理解是 像B+树的叶子节点一样包含了这个数据行的所有字段值,这就是聚簇。聚簇索引中包含了所有字段的值这样当索引扫描的这个字段时就不用再到表中进行查询,整个索引查询操作使用索引树就可以完成。

  • 非聚簇索引
    MyISAM引擎底层实现的就是非聚簇索引,它的叶子节点和B+树不同,MyISAM引擎的叶子节点存储了主键id以及数据对应的存储地址,当我们索引到这条数据需要其他字段时,就需要根据存储地址进行查找

  • hash索引
    hash索引使用是上面所说的hash数据结构,优缺点在上面已经说明,一般不适用hash索引

  • 联合索引
    简单介绍:联合索引就是由表中几个字段联合起来创建的一种索引类型,根据B+树的特性 联合索引的叶子节点上一样存储有联合的三个字段的值以及当前数据的主键,而根节点和非叶子节点存储的则是联合字段的值。当查询条件的所有字段都在联合索引的索引树中时就不需要再根据叶子节点的id到主键索引(聚簇索引)中进行查询而这个查询的过程我们称之为叫做回表,引用一张图叶子节点的绿色为主键id,白色为数据存储。
    联合索引的最左前缀原则:根据联合的第一个字段进行排序,这样一来第二个字段就是无序的,所以我们在使用联合索引时一定注意 字段的使用顺序,以及联合索引的字段的是否缺失。
    mysql索引树结构分析_第7张图片

  • 覆盖索引
    利用上图写一个sql语句这条sql语句看似会走联合索引其实不一定(mysql 会根据cost成本计算判断是否会走联合索引),因为select 的字段是所有的字段,联合索引的字段只有三个,如果使用联合索引则需要进行回表操作,mysql会评估性能上是否会比全表扫描要快。

select * from table_name where name='Bill' age='30' position='dev'

而对于这条sql的优化在一定的场景下我们需要用索引的字段来代替select * 例如,这样就为覆盖索引。

select name,age,positoon from table_name where name='Bill' age='30' position='dev'
  • 唯一索引
    根据某个字段进行排序,叶子节点存储有主键id使用的也是B+树mysql索引树结构分析_第8张图片

你可能感兴趣的:(关于mysql的那些事,mysql)