1、索引的定义
索引定义:索引是帮助MySQL高效获取数据的排好序的数据结构
为什么需要索引,mysql表中的数据,都是存储在磁盘中,而且不是不规律的,对磁盘的I/O操作是很消耗性能的、数据不规律的原因,例如:表中第一次新增了一条数据,存储在了磁盘中的A区域,过了一会又存储了第二条数据,那么第二条数据,不一定就存储在A附近的磁盘空间里,因为在间隔的时间中,可能存在其他程序运行将A旁边的磁盘占满,因此,第二条数据可能存储在E区,所以每一次的I/O都是很消耗性能的。
画黑板,敲重点,索引定义的 关键词,排好序、数据结构,首选是数据结构;
2、索引的数据结构
我们知道mysql索引底层使用的是b+树,所以我们要明白为什么选用b+树,而不选择其他的。(其他的包括:二叉树、红黑树、hash表、b-树;)
2.1 二叉树
如图1所示,如果我们需要查询col2=89的数据,在没有索引的情况下,我们需要进行6次查询才能最终获取结果,如果索引是二叉树,根据二叉树的特性,我们需要三次就可以查询到数据。
不能使用二叉树的原因,如果面对索引字段是自增的情况,若查询col1=6数据,也需要查询六次才能找到数据,所以二叉树不符合,如下图
2.2 红黑树
红黑树称二叉平衡,他可以避免上述二叉树的弊端,但是面对大数量的数据时,红黑树的高度不可控,因为,每一次查询节点,都是一次对磁盘的I/O操作,百万数据若使用红黑树,那么查询数据最多可能需要进行几十次的I/O操作,每一次的I/O操作都是很耗费性能的操作,因此红黑树数据结构是不满足mysql需求的
2.3 B-树
为了解决红黑树的弊端-------数据量太大导致树的高度不可控,B-树将节点内存扩大,每个节点可以存储很多节点。将树的高度维持在3,因此解决了树高度不可控的问题,且节点中的数据key从左到右递增排列,叶节点的指针为空 如下图所示,好像b-树已经解决上述所有数据结构的问题。但为什么使用的是b-树的变种(b+树),而没用使用B-树呢。接着分析B+树的结构
2.4:B+树
b+树在b-树基础进行了改变
1、非叶子节点不存储data,只存索引(冗余索引) 可以存放更多索引
2、叶子节点包含所有索引字段
3、叶子节点用指针连接,提高区间访问的性能
4、折半查找计算存储的节点
show global status like 'innodb_page_size’命令
可以查询节点存储的内存大小,(16KB),假设考虑字段类型有文本情况,一行数据大小为1KB,则节点能存储16条。
我们可以计算一下一个节点能够存储多少索引,假设主键类型是bigint(8个字节)
计算结果如下图
两千万的数据在B+数中的树的高度只有3,说明最多进行3次I/O,相对于没有索引则可能需要几千万次IO,对比优劣可见,再者,mysql可能会把根节点放在内存中(常驻内存),则叶子节点就不需要进行I/O操作,且mysql有的版本是将所有的非叶子节点都存放在常驻内存中,那么实际查询数据,可能只用进行一次I/O操作。