关于索引
1、 索引的概念:索引是帮助MySQL高效获取数据的排好序的数据结构
2、索引数据结构
- 二叉树:右边节点比左边节点大,右边子元数大于父元素,对于单边增长的数据提升效率很低
- 红黑树:二叉平衡树,会自我平衡,数据量大时,树的高度很大
- Hash表:
- 对索引的key进行一次hash计算就可以定位出数据存储的位置
- 很多时候Hash索引要比B+ 树索引更高效
- 仅能满足"+",“IN”,不支持范围查询
- hash冲突问
- B-Tree
- 叶节点具有相同的深度,叶节点的指针为空
- 所有索引元素不重复
- 节点中的数据索引从左到右递增排列
- B+Tree
- 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
- 叶子节点包含所有索引字段
- 叶子节点用指针连接,提高区间访问的性能
B-Tree和B+Tree的主要区别B+Tree非叶子节点不存储数据B-Tree存储,B+Tree范围查找效率很高
B+tree 是MySQL中被存储引擎采用最多的索引类型。B+tree 中的 B 代表平衡(balance),而不是二叉(binary),因为 B+tree 是从最早的平衡二叉树演化而来的。下面展示B+tree数据结构与其他数据结构的对比。
B+tree与B-tree的对比
B-tree 中的每个节点根据实际情况可以包含多条数据信息和子节点,如下图所示为一个3阶的B-tree:
相对于B-tree,B+tree有以下两点不同
- B+tree 非叶子节点只存储键值信息, 数据记录都存放在叶子节点中。而B-tree的非叶子节点也存储数据。所以B+tree单个节点的数据量更小,在相同的磁盘I/O次数下,能查询更多的节点。
- B+tree 所有叶子节点之间都采用单链表连接。适合MySQL中常见的基于范围的顺序检索场景,而B-tree无法做到这一点。
查找速度和树的高度很有关
为什么需要索引?数据存储在硬盘是随机的,在进行访问的时候会进行磁盘I/O交互,索引就是减少交互,有索引会大大提升效率
mysql索引B+Tree的非叶节点的大小为16Kb,bigint8个字节,地址为6字节,16kb/(8+6)b=1170元素,两千多万的元素,msyql会把根节点放内存
B+Tree的高度是由非叶子节点存放的索引元素决定
MySQL存储引擎
1、MyISAM
叶子节点存放的是数据地址,索引存放在.MYI文件中,数据存放在MYD文件中
2、InnoDb(聚集) (.ibd文件)
- 表数据文件本身就是按B+Tree组织的一个索引结构文件
- 聚集索引-叶节点包含了完整的数据记录
聚簇索引的每个叶子节点存储了一行完整的表数据,叶子节点间按id列递增连接,可以方便地进行顺序检索。
InnoDB表要求必须有聚簇索引,默认在主键字段上建立聚簇索引,在没有主键字段的情况下,表的第一个非空的唯一索引将被建立为聚簇索引,在前两者都没有的情况下,InnoDB将自动生成一个隐式的自增id列,并在此列上建立聚簇索引。
面试题:
1、为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?
mysql数据库的资源是很宝贵的,不建主键的话mysql会自动建一列唯一的rowid,或者挑一列数据作为索引,
整型方便比较,提交性能,占用空间小;非自增主键会引起树的分裂和平衡影响效率
2、为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间,减少复杂度)
组合索引
索引最左前缀原理