持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
MySQL官⽅对索引的定义是:索引(Index)是帮助MySQL⾼效获取数据的数据结构。
索引最形象的⽐喻就是图书的⽬录。注意只有在⼤量数据中查询时索引才显得有意义。
在MySQL中索引是在存储引擎层实现的,⽽不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。
一、索引的本质
索引的本质是一种排好序的数据结构。
二、索引的分类
1、按物理存储分类:聚集索引、⾮聚集索引(也叫⼆级索引、辅助索引)。
- 聚集索引: 将数据存储与索引放到一块,索引结构的叶子节点保存了行数据,必须有且只有一个。
- 二级索引: 将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键,可以存在多个。
- 注意,一定会有聚集索引:
1.默认主键为聚集索引;
2.如果不存在主键,将使用第一个唯一(unique)索引作为聚集索引;
3.上述都没有,则innodb会自动生成一个rowid作为隐藏的聚集索引。
-
回表查询:
是指先根据二级索引查到键值,然后通过键值回表查询聚集索引,从而获取行(row)数据。
2、按字段特性分类:主键索引(PRIMARY KEY)、唯⼀索引(UNIQUE)、普通索引(INDEX)、全⽂索引(FULLTEXT)。
- 主键索引:针对于表中主键创建的索引,默认自动创建,只能有一个,primary。
- 唯一索引:避免同一个表中某数据列中的值重复,可以有多个,unique。当你为某个字段创建唯一约束时,会自动创建唯一索引。
- 常规索引:快速定位特定数据,可以有多个。
- 全文索引:查找的是文本中的关键字,而不是比较索引中的值,可以有多个。
3、按字段个数分类:单列索引、联合索引(也叫复合索引、组合索引)。
- 单列索引:单个字段构建的索引。
- 联合索引:多个字段组合的联合索引。
4、按数据结构分类:B+tree索引、Hash索引、二叉树、。
Hash 索引:
Hash 索引是比较常见的一种索引,他的单条记录查询的效率很高,时间复杂度为1。但是,Hash索引并不是最常用的数据库索引类型,尤其是我们常用的Mysql Innodb引擎就是不支持hash索引的。主要有以下原因: Hash索引适合精确查找,但是范围查找不适合
二叉树:
常见的索引使用的数据结构是树结构,首先我们来介绍下最经典的二叉树。
先来介绍下二叉树的特点:
-
- 二叉树的时间复杂度为 O(n);
-
- 一个节点只能有两个子节点。即度不超过2;
-
- 左子节点 小于 本节点,右子节点 大于 本节点;
-
- 极端情况下二叉树会链化成单一链表;
-
二叉树中,有一种特殊的结构——平衡二叉树,
平衡二叉树的特点:
根节点会随着数据的改变而变更; 数据量越多,遍历次数越多,IO次数就越多,就越慢(磁盘的IO由树高决定)
B树(二三树)
B 树大概是这样子的:
从B树的结构图中可以看到每个节点中不仅包含数据的 key 值,还有 data 值。
而每页的存储空间是有限的,如果 data 比较大,会导致每个节点的 key 存储的较少,当数据量较大的时候,同样会导致B树很深,从而增加了磁盘 IO 的次数,进而影响查询效率。
B+树
MySQL 中最常用的索引的数据结构是 B+ 树,他有以下特点:
- 在 B+ 树中,所有数据记录节点都是按照键值的大小存放在同一层的叶子节点上,而非叶子结点只存储key的信息,这样可以大大减少每个节点的存储的key的数量,降低B+ 树的高度;
- B+ 树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针;
- B+ 树的层级更少:相较于 B 树 B+ 每个非叶子节点存储的关键字数更多,树的层级更少所以查询数据更快;
- B+ 树查询速度更稳定:B+ 所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定;
- B+ 树天然具备排序功能:B+ 树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。
- B+ 树全节点遍历更快:B+ 树遍历整棵树只需要遍历所有的叶子节点即可,而不需要像 B 树一样需要对每一层进行遍历,这有利于数据库做全表扫描。
好了说了这么多的 B+ 树的特点,我们来张图看看 B+ 树到底长什么样子:
上面的数据页就是实际存放数据页的地方,且数据页之间是通过双向链表进行连接的。
MySQL 在存储数据的时候是以数据页为最小单位的,且数据在数据页中的存储是连续的,数据页中的数据是按照主键排序的(没有主键是由 MySQL自己维护的 ROW_ID 来排序的),数据页和数据页之间是通过双向链表来关联的,数据与数据时间是通过单向链表来关联的。
三、聚簇索引、覆盖索引和非主键索引
聚簇索引 MySQL基于主键索引结构创建的B+树,也是二叉搜索树的一种,数据仅仅存储在叶子节点,这种集索引页+数据页组成的组成的B+树就是**聚簇索引*。
覆盖索引(covering index),MySQL只需要通过索引就可以返回查询所需要的数据,而不必在查到索引之后再去回表查询数据,所以相当快!!但是同时也要求所查询的字段必须被索引所覆盖到,在Explain的时候,输出的Extra信息中如果有“Using Index”,就表示这条查询使用了覆盖索引。
非主键索引一般都是联合索引,在维护 B+ 树的时候,会根据联合索引的字段依次去判断,假设联合索引为:a + b + c,那么 MySQL 在维护该索引的 B+ 树的时候,首先会根据 a 进行排序,a 相同的话会根据第二个 b 排序,如果 b 也一样,那么就会根据 c 去排序,如果 c 也一样,那么就会根据主键字段值去排序,且对于非主键索引,MySQL 在维护 B+ 树的时候,仅仅是维护索引字段和主键字段。
参考学习网址: