什么是索引?
官方定义:索引(Index)是帮助MySQL高效获取数据的数据结构。
索引结构设计
为什么要有索引?数据结构的选择,无非就是时间复杂度的选择。本质上是查找算法,即通过最少的I/O次数,便能检索到目标数据。
索引数据结构的演进:二叉树 --> 二叉查找树 --> 平衡二叉查找树 --> 多路平衡查找树(B Tree) --> 加强版多路平衡查找树(B+ Tree)
二叉查找树
二叉查找树:基于二叉树,加入了左子数必须小于父节点,右子数必须大于父节点的规则。但是会存在极端情况--斜树(左斜或者右斜),这会导致树的深度过深,树的深度越深意味着I/O次数越多。
平衡二叉查找树
平衡二叉查找树:基于二叉查找树,加入了节点旋转的规则。通过旋转,减少数的深度。但是每个节点只能有一个关键字,效率也并不是很高。
多路平衡查找树(B Tree)
多路平衡查找树(B Tree):基于平衡二叉查找树,在节点中可以存储多个关键字,意味着分叉数越多,也就降低了树的深度,从而减少I/O的次数。
B Tree特点:分叉树(路数)永远比关键字数多1。

加强版多路平衡查找树(B+ Tree)

B+树相比B树的优化:
1.B树的路数和关键字的个数关系不再成立,数据检索规则采用的是左闭合区间,路数和关键词数为1比1.
2.B+树的根节点和枝节点都不会存储数据,只有叶子节点才会存储数据,并且每个叶子节点都会增加一个指针指向相邻的叶子节点,形成一个有序链表结构。
3.B+ 树关键字的搜索采用左闭合区间。
4.B+ 树的根节点和枝节点不存储数据,只有叶子节点才存储数据内容或者是内容的地址。而在B树中,如果命中了节点,则会直接返回数据(因为关键字和数据存储在一起)。
5.B+树中,叶子节点不会保存子节点的引用。
MySQL为何选择B+树?
1.扫库、扫表能力更强。(当需要对全表进行扫描时,只需要遍历叶子节点即可,不需要遍历整个B+树)
2.B+树的读写能力更强。(一个节点可以保存更多的关键字,减少I/O次数)
3.排序能力更强。(叶子节点是有序的链表结构)
4.效率更加稳定。(永远是在叶子节点获取数据,I/O次数是稳定的)
MyISAM引擎的索引实现
在MyISAM里面,另外有两个文件:
InnoDB的索引实现
在InnoDB中,只有一个ibd文件,里面包含索引和数据。 在B + Tree中的叶子节点存储了索引对应的数据行,所以我们称 InnoDB中索引即数据、数据即索引。

聚簇索引和非聚簇索引
聚簇索引:就是指索引键值的逻辑顺序和表数据行的物理存储顺序一致。只有聚簇索引才会在叶子节点缓存表中的数据。
非聚簇索引:除了主键索引以外,其他索引均属于非聚簇索引,非聚簇索引的叶子节点不会存储表数据

从上面这个图可以看到,真正的数据仍然是保存到主键索引的叶子节点(这也就是为什么InnoDB表必须要有主键的原因),而辅助索引的叶子节点的数据区保存的是主键索引的关键字的值(非主键索引叶子节点的逻辑顺序和磁盘顺序不一致)。
MyISAM和InnoDB两种引擎索引区别

索引创建建议
1.在用于where判断、order排序、join on 、group by 的字段上创建索引。
2.索引不易太多。
3.对于过长的字段,建议建立前缀索引。
4.区分度低的字段,不要建索引。(离散度太低,导致扫描行数过多)
5.频繁更新的值,不要作为主键或者索引。(B+树的平衡导致 页分裂,影响效率)
6.随机无序的值,不建议作为索引,例如身份证、UUID。(无序,页分裂)
7.组合索引把离散度高(区分度高)的值放在前面。
8.创建复合索引,而不是修改单列索引。
索引失效
1.索引列上使用函数(sum、count、avg等)、表达式。
ps:https://www.runoob.com/mysql/mysql-functions.html
2.字符串不加引号,出现隐式类型转换。(出现隐式转换,会导致全表扫描)
eg:
3.like条件中前面带%。(最左匹配原则)
4.负向查询。
Not Like:

!= (<>)和NOT IN 在某些情况下可以:

因为主键索引是有序的,因此只需要从1之后开始读取即可。
713

被折叠的 条评论
为什么被折叠?



