索引常用的数据结构

索引的本质

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

常见的索引类型

BTree:多路平衡搜索树

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

B+Tree(B-Tree变种)

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

Hash

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

InnoDB索引实现

主键索引(聚簇索引)

基本介绍

  • 表数据文件本身就是按B+Tree组织的一个索引结构文件
  • 聚簇索引-叶节点包含了完整的数据记录
    聚簇索引.png

为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?

  • 如果设置了主键:那么InnoDB会选择主键作为聚簇索引、如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚簇索引(ROWID随着行记录的写入而主键递增)。
  • 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,主键的顺序按照数据记录的插入顺序排列,自动有序。当一页写满,就会自动开辟一个新的页
  • 如果使用非自增主键:由于每次插入主键的值近似于随机,因此每次新记录都要被插到现有索引页的中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

非主键索引

基本介绍

  • 非主键索引结构叶子节点存储的是主键值
    非主键索引.png

为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

  • 一致性:一个表只能有一个聚簇索引,只在唯一的一个聚簇索引上维护数据。聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。
  • 节省维护索引的开销:每次修改数据只需要在一处维护全部的字段信息。
  • 节省存储空间:一个组件字段信息与全部字段需要的空间相差太多,重复存储很浪费磁盘空间。

联合索引

  • 索引最左前缀原理
    联合索引.png
posted @ 2021-12-12 14:18  程序java圈  阅读(116)  评论(0编辑  收藏  举报