【数据库】Mysql索引究竟是什么?

  • 索引概念
  • B+树存储索引
  • InnoDB与MyISAM存储引擎的异同
  • 补充知识

索引概念

  • 索引是帮助 MySQL(或其他数据库)高效获取数据的排好序的数据结构;

  • 索引的数据结构有二叉树,红黑树,Hash表,B树等,Mysql使用的是B+树;

  • Mysql用B+树存储是有原因的:

    ①之所以不用二叉树存储,是容易让树变成单边树,这并不会提高查询效率;

    ②虽然红黑树(二叉平衡树)自带左右两边平衡节点的作用,但是由于红黑树在一个节点下最多只允许2个孩子节点,因此容易造成当数据量特别大的时候树的深度太深,对查找元素不利;

    ③将红黑树的每个节点的单个元素扩容到多个元素,每个孩子节点也扩容到多个元素,就变成了B树,而InnoDB不使用B树存储索引的的原因跟InnoDB的数据存储结构有关,下文中会详细说明;

    ④Hash是一种散列算法,性能非常高,当数据库使用Hash算法做索引的时候,会对查询的条件做Hash运算,算出的值可以映射到磁盘地址,从而找到数据;但是这种算法有很大的局限性,对范围查找,模糊查找支持都不友好,因此在数据库99%的场景都是使用B+树,当应用场景只有等值查找的时候,Hash算法做索引的优势才会显现出来;

  • B树的结构如下图:

1584430549625.png

B+树存储索引

  • B+树实际上也是一颗多路二叉树:每一个节点左边的元素都是小于节点的,右边的元素都是大于等于节点的;

B+树特点

  • 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引;
  • 叶子节点包含所有索引字段;
  • 叶子节点间用指针连接(Mysql的InnoDB的B+树是双向连接,头尾相连,而原生的B+树是单向指针),提高区间访问的性能。

Mysql的B+树索引

  • Mysql的InnoDB引擎默认使用B+树存储索引;
  • **Mysql的叶子节点只存储索引(冗余)的原因:**索引的根节点会预先加载到内存,Mysql在执行查询的时候会先在根节点进行比较,然后进行一次磁盘IO去加载子节点,进而找到数据位置;如果非叶子节点只存储索引的话,那么相同的内存空间就可以存放更多的索引,查询效率会大大提升(一般只需要2次磁盘IO);
  • Mysql的B+树存储索引默认每个节点最大数据量16KB(show global status like 'Innodb_page_size';),算出来后每个节点大约可以存储1170个索引,深度为2的B+树就可以容纳的数据量可以达到1170*1170 = 1,368,900‬个索引;
  • 一般Mysql存储数据超过2000万行就要做分库分表了,也就是一般Mysql的B+树深度一定在2-4层之间。

InnoDB与MyISAM存储引擎的异同

  • 数据库的存储引擎是表级别的,不同的表可以指定不同的存储引擎;

  • Mysql常用的两种存储引擎:①MyISAM:索引存储在MDI文件,数据存储在MYD文件,表结构存储在FRM文件;②InnoDB:表结构存储在FRM文件,数据与索引存储在IBD文件;

  • 聚集索引:索引与数据记录一起存储为聚集索引(InnoDB),索引与数据记录分开存储为非聚集索引(MyISAM);

  • InnoDB的非主键索引和主键索引存储结构差距比较大,而MyISAM引擎的非主键索引和主键索引存储结构没区别;(由于聚集索引和非聚集索引而导致的区别)

InnoDB的索引

  • InnoDB是典型的聚集索引结构(使用B+树组织存储具体数据),如下图,正由于此特性,因此使用InnoDB的时候,必须要有主键(如果建表的时候没有建主键,存储引擎会自动增加一列数据作为主键),并且要使用自增ID(每次都是在最后位置插入元素,避免中间插入元素引起的维护树结构带来的性能开销,如果需要支持分库分表,可以使用雪花算法生成的ID)的整型数据(便于范围查找)作为主键;
  • 千万不要让UUID成为一个表中的主键,占用空间并且字符串运算的成本一定大于整型;
  • 在叶子节点中,所有的索引数据都是从左到右以此递增,而且每个叶子节点都会指向下一个叶子节点,这就是便于范围查找(也是我们不使用Hash和B树作为索引存储方法的原因);
  • 联合索引:在B+树索引位置(下图中绿色区域)存储多个字段的值,在比大小的时候,按建索引时的从左到右原则(比如:MyIndex(id,name,age)),如果左边第一个字段的值一样,则根据第二个字段的值比大小,以此类推;

1587143162361.png
  • 为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)如果同样的数据存储多份,不同的索引进行维护的时候就有数据一致性问题,会引入事务问题,而事务是会大大降低性能的,并且出于存储空间的问题,真实的数据是只存在一份的;在使用非主键索引的时候,会在非主键索引的B+树中查找到具体数据的主键值,然后用主键值去主键索引B+树中找到具体的数据;

1587143120363.png

补充知识

  • 一个特别好用的数据结构插入与查找的动态动画演示网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html;

注意:本文归作者所有,未经作者允许,不得转载

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Maoway稻草人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值