MySql索引的数据结构与算法

MySql索引的数据结构与算法

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

索引数据结构

  • 二叉树

  • 红黑树

  • hash表

    • 不支持范围查询,对 = 查询查询效率高
    • 存储方式
      • 进行哈希运算获取hash槽,然后将对应的数据存储在hash槽内
      • 如果存在hash碰撞,将会在hash槽内生成一个链表,进行存户在后面,查找的时候会将当前槽内的数据全部取出来,然后查询.
  • B-Tree

    • 叶子节点携带完整的数据结构,叶节点指针为空
    • 所有索引元素不重复
    • 节点中的索引从左到右自增
  • B+Tree

    • 非叶子节点不存储数据,被称为冗余节点,可以存储更多的节点
    • 叶子结点存储双向指针,指针指向前后节点地址,提高区间方位性能
    • 叶子节点包含所有的索引字段

红黑树结构

​ 当一边的结构过于深的时候会进行一次重排,让树结构相对来说平衡

MySql索引的数据结构与算法_第1张图片

​ 二叉树 结构

​ 如果数据为线性增长的数据则会变成单边树

MySql索引的数据结构与算法_第2张图片

B-Tree数据结构

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

MySql索引的数据结构与算法_第3张图片

B+Tree数据结构(Mysql使用的数据结构)

  • B-Tree的变种,在非叶子结点不存储数据,值存储索引(冗余索引),可以放更多的索引
  • 叶子节点包含所有的索引字段
  • 叶子节点用指针连接,提高区间方位的性能
  • 叶节点具有相同的深度
  • 叶子节点的数据是大于等于父节点的

他解决了红黑树的高度不可控的问题

MySql索引的数据结构与算法_第4张图片

mysql为什么选择B+Tree不选择B-Tree?

​ 因为B+Tree的索引结构决定的,B+Tree的非叶子节点不存储数据,这样在查找的时候load进入内存的时候能够load更多的索引,内存在load的时候只会一次load16KB的内容,如果飞叶子结点存储的数据就会导致占用更多的空间,B+Tree在飞叶子结点不存储数据,每个非叶子节点的索引为int类型的话,一个节点会占用8bit大小,下级非叶子索引占用的位置为6bit,这样的索引在load的时候一次大概会load的条数1170条,三层这样的结构会load大概2100万条,大大增加的查询效率,减少了磁盘IO,B+树指针

​ B-Tree树会在每一个节点下面存储数据,这样在检索load进入内存的时候数据也会被load进去,减少了索引的数量,如果是相同数量级别的表,深度会很深,大大增加了磁盘IO的次数

存储引擎

MyIsam存储引擎

frm:表结构 from

MYD:MyIsamData表内容

MYI:MyIsam Index 表索引

  • 存储结构,数据库表解构(.frm),表内容(MYD),表索引(MYI)是分开存储的(非聚簇索引)

查找方式:

1:使用B+Tree的数据结构将索引load进入内存,

2:查找到指定索引(MYI),去找到对应的存储位置

3:通过对应的位置,去MYD表中取找对应的数据

InnerDB存储引擎

frm:表结构

idb:表数据和index索引的存储

  • 表数据文本本身就是一个使用B+Tree维护的索引结构文件
  • 聚集索引-叶子节点包含了完整的数据结构
  • 建议维护一个整形自增的主键作为一个主键索引
    • 为什么建议维护一个自增主键作为索引?
      • 为什么维护一个主键作为索引?
        • 如果不自己维护一个索引,那么InnerDB存储引擎会自己在内部进行维护一个主键索引,当做文件的索引
      • 为什么需要一个自增的主键?
        • 因为B+Tree维护的索引是一个有序的索引,如果在索引中间插入一些别的数据,会让索引重新排序,过程中还可能会产生分列,影响性能
  • 为什么非主键索引结构叶子结点存储的是主键的值
    • 1:存储主键的值,可以避免数据一致性,这样在新增数据的时候不需要在维护一份数据在非主键索引上
    • 2:节省内存空间,不用存储完整的数据结构
    • 会出现什么问题?
      • 如果去查询非主键索引,会进行回表操作,当查询到非主键索引,会获取主键索引的下标,然后通过当前下标再次进入idb文件通过主键索引再次去查询数据

什么是联合索引?
MySql索引的数据结构与算法_第5张图片

联合索引是多个索引组合在一起的索引,在进行查询的时候需要保证最左前缀原则!

例:

​ select * form table where name = “q” and age =“30”

​ select * form table where age =“30”

​ select * form table where age =“30” and position = “dev”

  • 其中只有第一个会走索引,是因为保证了最左前缀原则
    • 第二个查询和第三个查询为什么不会走索引?
      • 因为B+Tree的索引进行了排序,name在最前面,他需要先对name进行排序,如果那么相同的情况下才会对age和position进行排序,
      • 查找的时候如果直接进行查找第二个和第三个字段,就没办法通过排序进行查找数据,需要进行全表扫描,无法走索引

你可能感兴趣的:(mysql,数据库)