Mysql索引数据结构详解
本文相关内容目录:
1.索引数据结构红黑树,Hash,B+树详解
2.千万级数据表如何使用B+树索引快速查找
3.聚集索引&聚簇索引&稀疏索引到底是什么
4.为什么DBA总推荐使用自增主键做索引
5.联合索引底层数据结构又是怎样的
6.Mysql最左前缀优化原则是怎么回事
索引:是帮助Mysql高效获取数据的排好序的数据结构
索引数据结构:
二叉树 :
缺点:如果是按数字递增的话,容易形成链表,如同全表扫描一样,没什么区别 所以没用这个数据结构
红黑树:二叉树的升级版,也叫二叉平衡树
缺点:数的高度不行,如果数据太多的话,那导致树的高度很高,所以也不是mysql选择的数据结构
B -Tree :叶节点具有相同的深度,叶节点的指针为空
所有索引元素不重复
节点中的数据索引从左到右递增排列
Mysql 也没有选择这个数据结构,因为mysql使用了B-Tree的变种B+Tree,在非叶子节点不存储data,
只存储索引,可以放更多的索引
B+Tree:
非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
叶子节点包含所有索引字段
叶子节点用指针连接,提高区间访问的性能
如果我们查询的是30
查询的过程:
注意:上图的空白处存储的是下一节点的地址
1.先将索引的根节点都加载到内存
2.根据某种算法(二分查找法)
3.我们定位到15-56之间的位置,我们根据空白处存储的位置,找到下一个节点
4.然后把下一个节点的全部索引也加载到内存,然后类似,定位到20-49之间,以此类推
hash结构:
对索引的key进行一次hash计算就可以定位出数据存储的位置
很多时候Hash索引要比B+ 树索引更高效
仅能满足 “=”,“IN”,不支持范围查询
hash冲突问题
InnoDB索引实现(聚集)
表数据文件本身就是按B+Tree组织的一个索引结构文件
聚集索引-叶节点包含了完整的数据记录
为什么建议InnoDB表必须创建主键,并且推荐使用整型的自增主键?
Mysql会自动的帮你找到一个合适的唯一索引作为主键,若找不到符合条件唯一索引条件的字段时,会生成类似于ROW_ID的虚拟列充当该InnoDB表的主键
整型的存储比字段类型要小,而且应为是InnoDB存储引擎使用的是B+Tree数据结构,在进行查询数据是需要对每个元素进行比较,而整型的对比效率是高于其他数据结构的,字符串等
使用自增主键作为InnoDB表的主键会存在一个问题?
Mysql中innodb_page_size = 16kb,选择BIGINT作为主键占用8b,地址也占8b 16kb/(8+8)b = 1000个元素,也就是1001阶的B+Tree树结构,那么每次新增新增一条记录都是在最右边的数据中插入新的数据,当插入1001个元素时,发生列变生成一个新的根节点,而此时的左子节点包含的元素个数是(1001-1)/2=500,此后不会再发生改变,因为每次插入的数据都是在整棵树的最右侧,以此类推会发现会有近乎一半的节点空间是浪费的。下图是以7阶的B+Tree示例
注意: innodb 只有一个聚集索引,对于其他的索引,都是非聚集索引,都要有一个回表的查询
为什么非主键索引结构叶子节点存储的主键值?
一致性和节省空间
- 数据冗余。虽然提升了查询性能,但是需要更多的空间来存储冗余的数据。
- 维护麻烦。一个地方修改数据,需要在多棵索引树上修改