索引的作用
类似于一本书中的目录,通过目录我们可以快速的翻到某一章节,而索引在数据库中便起到了同样的作用,优化查询
BTREE的演变
BTREE查找算法演变
B-TREE : 普通 BTREE,平衡多路查找树(B-Tree)
B+TREE : 叶子节点双向指针
B++TREE(B*TREE):枝节点的双向指针
1)B-TREE,普通 BTREE,平衡多路查找树
- 叶子节点:包含的条目直接指向表里的数据行。叶子节点之间彼此相连,一个叶子节点有一个指向下一个叶子节点的指针。
- 分支节点:包含的条目指向索引里其他的分支节点或者叶子节点。
- 根节点:一个 B-树索引只有一个根节点,实际上就是位于树的最顶端的分支节点。
首先要明白的是,系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一个磁盘块中的数据会被一次性读取出来,而不是需要什么取什么
另外每个节点都会占用一个盘块的磁盘空间
每个节点保存的是子节点的一个取值范围,根据取值范围来判断下次一次应该将那块磁盘读入内存进行查找数据
2)B+TREE(叶子节点双向指针)
从上图看出,在B+Tree上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有叶子节点(即数据节点)之间是一种链式环结构。
B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。从上图中的B-Tree结构图中可以看到每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。
在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。而BTree,这个是以B+Tree为基础,在非叶子结点(枝节点)上增加了链表指针,BTree的空间利用率更高。
我觉得就是兄弟节点之间多了指针,再查找的时候可以使范围更精确
补充:加深理解传送门
如何使用BTREE
聚簇索引(主键)
聚簇索引也叫集群索引,聚集索引。它不是一种单独的索引类型,而是一种数据存储方式。
Innodb的聚簇索引实际上在同一个结构中保存了B*Tree索引和数据行。当表有聚簇索引时,数据行实际上存储在索引的叶子节点中。
聚簇的意思是表示数据行和相邻的键值紧凑地存储在一起。一个表只能有一个聚簇索引。也就是按照每张表的主键构成一棵B+树,叶子节点中存放整张表的行记录数据,也将聚集索引的叶子节点成为数据页,每个数据页之间通过一个双向链表来进行链接。
数据页存放的是每行的所有记录,非数据页存放的是键值和指向数据页的偏移量。它可以在叶子节点直接找到数据,且对于主键的排序查找和范围查找速度非常快,因为聚集索引是逻辑上连续的。
比如查询后10条数据,由于B+树索引是双向链表,可以很快找到随后一个数据页,然后取出最后的10条数据。
前提条件
1.如果表中设置了主键(例如ID列),自动根据ID列生成索引树。
2.如果没有设置主键,自动选择第一个唯一键的列作为聚簇索引
3.如果没有唯一键,自动生成隐藏的聚簇索引。
4.在建表时,推荐创建主键为数字自增列。
功能
1.录入数据时,按照聚簇索引组织存储数据,在磁盘上有序存储数据行。
2.加速查询(基于ID作为条件的判断查询)。
聚簇索引的B*Tree构建过程
叶子节点: 存储数据行时就是有序的,直接将数据行的page作为叶子节点(相邻的叶子结点,有双向指针)
枝节点 : 提取叶子节点ID的范围+指针,构建枝节点(相邻枝节点,有双向指针)
根节点 : 提取枝节点的ID的范围+指针,构建根节点
辅助索引(自己想要添加的,比如姓名)
辅助索引需要人为创建辅助索引,将经常作为查询条件的列创建辅助索引,起到加速查询的效果。
也称非聚集索引,按照每张表创建的索引列创建一棵B+树,叶子节点并不包含行记录的全部数据。叶子节点包含键值 和 书签,书签用来告诉InnoDB存储引擎在哪可以找到与索引对应的行数据,每张表可以有多个辅助索引。
如果某个查询是通过辅助索引查找数据的,则查找过程为:先遍历辅助索引并找到叶节点找到指针获取主键索引的主键,然后通过主键索引找到对应的页从而找到一个完整的行记录。
注:没执行一次查询就是一次IO,比如 辅助索引树高度为3,聚集索引树高度为2,则通过辅助索引查询数据时就要进行3+2次逻辑IO最终得到一个数据页。
辅助索引的B*Tree 构建过程
叶子节点:提取主键(ID)+辅助索引列,按照辅助索引列进行从小到大排序后,生成叶子节点。(多个辅助索引列,以最左边的列为标准。相邻的叶子结点,有双向指针。)
枝节点 :提取叶子节点辅助索引列的范围+指针,构建枝节点(相邻枝节点,有双向指针)
根节点 :提取枝节点的辅助索引列的范围+指针,构建根节点
辅助索引查询过程
按照辅助索引列,作为查询条件时。
- 查找辅助索引树,得到ID值
- 拿着ID值回表(聚簇索引)查询
单列索引
-- 只拿一个非主键列来创建索引
select * from test.t100w