MySQL中InnoDB数据结构和索引介绍
一、为什么选用B+Tree
为何数据库中选用数据结构作为索引
- 数组:查询时间还行,当时插入和更新很慢。
- 链表:查询时间长。
- hash : 定位效率高,但是没有顺序性。
- 树结构:B+树在查询和插入都是非常适合的
为什么选用B+Tree
- B+树是B-树的变种的多路绝对平衡查找树,他拥有B-树的优势
- B+树扫库、表能力更强
- B+树的磁盘读写能力更强
- B+树的排序能力更强
- B+树的查询效率更加稳定
二、B+Tree介绍
b+树有个特点,数据都是存在子节点上(叶子节点)如下图:
特点:
其它节点只存索引,数据都是存在叶子节点上,而且叶子节点是有序的,在查询时有更高效率,而且这样的结构,不用存下一个节点磁盘位置信息,降低树的高度,而且节约空间,由于数据都存在叶子节点上,查询的次数恒定并且保证了查询速度。
总结:
- 由于非叶子节点只存储索引信息,数据只存叶子节点上,单个节点上的信息更少,这样非叶子节点在一个磁盘块就可以存储更多的,从而降低树的高度,这就意味着搜索深度降低了,对索引是个优化。
- 所有叶子节点都是有序的且有索引指向,当在搜索一个范围值的时候只需要找到两个叶子节点然后把中间数据全部返回即可。
三、Mysql B+Tree索引体现形式
MySQL在5.6版本开始采用Innodb,之前都是Myisam作为默认引擎
1、Myisam中B+Tree的存储形式
特点:
Myisam中B+Tree 的叶子节点存存的是据库中对应数据的地址,再通过地址命中查找的数据并返回,主键和辅助索引为同级别索引。
2、Innodb中B+Tree的存储形式
特点:
Innodb中B+Tree,主键索引叶子节点存储的不再是数据对应的存储位置,而是数据本身;辅助索引叶子节点存储的是数据对应的主键索引,命中后拿到对应的主键索值再去主键索引中搜索到具体的值返回。
总结:
由于Innodb 中,主键索引b+数的叶子节点上直接存的数据,无需再通过磁盘地址查找,速度会更快。如果非主键索引需要两次查找,首先查找辅助索引中对应的主键索引值,再从主索引的叶子节点上取数据。在索引变化是只需要更改主键索引,和辅助索引中对应的主键索引值,维护量相比于Myisam中同时维护所有索引,效率更高。
四、关于Innodb 中的索引知识
1、列的离散性
- 离散度在不超过全表的10%-15%的前提下索引才可以显示其所具有的价值
- 我们所追求的目标就是创建全表扫描所无法比拟的有效索引。
总结:
离散性越高 选择性就越好
2、最左匹配原则
对索引中关键字进行计算(对比),一定是从左往右依次进行, 且不可跳过
3、联合索引
- 单列索引
节点中关键字[name] - 联合索引
节点中关键字[name,phoneNum] - 单列索引是特殊的联合索引
- 联合索引列选择原则
1、经常用的列优先 【最左匹配原则】
2、选择性(离散度)高的列优先【离散度高原则】
3、宽度小的列优先【最少空间原则】
4、覆盖索引
- 如果查询列可通过索引节点中的关键字直接返回,则该索引称之为 覆盖索引。
- 覆盖索引可减少数据库IO,将随机IO变为顺序IO,可提高查询性能
总结:
- 索引列的数据长度能少则少。
- 索引一定不是越多越好,越全越好,一定是建合适的。
- 匹配列前缀可用到索引 like 9999%,like %9999%、like %9999用不到索引;
- Where 条件中 not in 和 <>操作无法使用索引;
- 匹配范围值,order by 也可用到索引;
- 多用指定列查询,只返回自己想到的数据列,少用select *;
- 联合索引中如果不是按照索引最左列开始查找,无法使用索引;
- 联合索引中精确匹配最左前列并范围匹配另外一列可以用到索引;
- 联合索引中如果查询中有某个列的范围查询,则其右边的所有列都无法使用索引;