一、索引的本质
**索引是帮助Mysql高效获取数据的排好序的数据结构**
二、Mysql索引数据结构
1、Hash表
-
对索引进行Hash算法,存储到Hash表中
-
优点
1) 对索引的Key进行一次Hash计算就可定位出数据存储位置
2) Hash索引有时候比B+Tree更高效(查询的数据位于链表头部位置) -
缺点
1) 仅能满足”=“、”IN“操作,不支持范围查询(基于Hash算法随机位于桶中,不能排序)
2) Hash冲突问题 -
基于优缺点应用情况:不需要进行范围、排序操作的,数据量没那么大(可能会Hash冲突)
2、B+Tree
介绍几种数据结构与B+Tree进行比较展示优缺点
- 二叉树
1) 可以明显看到根节点左边永远比根节点小,右边永远比根节点大
2) 以上图例可以明显看到二叉树的缺点:如果数据都比根节点大,会导致整个树失衡,数据极端情况下就变成链表结构,查找效率低。 - 红黑树(二叉平衡树)
1) 基于二叉树做了优化,当树结构失衡时,会进行反转、平衡。
2) 但是又带来新的问题,当数据量大的时候,树的高度会急剧增高,导致查询某个数据时,可能会遍历的次数过多,导致查询效率低下。 - B-Tree
1) 索引+数据都存储在非叶子节点
2) 叶子节点具有相同的高度,叶子节点的指针未空
3) 所有索引的元素不重复
4) 节点中的数据做因从左到右依次递增 - B+Tree
1) 非叶子节点不存储data,只存储索引(冗余索引)-> 可以存放更多的索引(Mysql默认每页16KB,如存储bigInt值8字节,两个索引之间存储下一页索引地址例6字节,则每个节点大概存储16KB*1024/(8+6)= 1170个。也就是每个节点大概存储1170个索引)
2) 叶子节点用指针连接,提高区间访问的性能(更快捷的范围查询)
三、存储引擎索引结构
1、MyISAM存储引擎索引结构
- 非聚集索引(索引文件与数据文件分开)
2、InnoDb存储引擎索引结构
- 聚集索引(索引文件与数据文件在一个文件)
四、面试题
1、为什么建议InnoDb表必须建主键,并且推荐使用整型的自增主键?
- 性能方面,如果不定义主键,Mysql则会根据表中某列不重复的值自主建立主键,如果全部列都存在主键则会默认生成主键,会消耗性能。
- 如果不使用整型主键,使用字符串,则查询数据时,会根据主键从左到右每个字符的ASCII码比较,会影响性能。
- 如果使用自增主键,则每次插入数据时,索引只需要放到最后面,不需要分裂某页的索引数据。
2、为什么非主键索引结构叶子节点存储的是主键值?
- 节省空间(如果不存储主键值,在生成非主键索引结构时,叶子节点存储的就是数据,由于主键索引叶子节点已经存储浪费空间)
- 由于主键索引对应的数据是唯一的,所以根据主键索引去查找肯定只能查找到一份