1.索引初识
索引是帮助MySQL高效获取数据的数据结构 ,索引是一个单独存储在磁盘上的数据结构,它们包含着对数据表里所有记录的引用指针,使用索引时可以提高数据库特定数据的查询速度,索引是在存储引擎中实现的,因此每种存储引擎的索引不一定完全相同,并且每种存储引擎也不一定支持所有的索引类型。
2.索引优缺点
2.1 优点
1.加快数据库的查询速度
2.通过创建唯一索引,可以确保数据库数据的唯一性
3.通过使用索引,可以在查询中使用优化隐藏器,提高系统的性能
2.2 缺点
1.索引是存储在磁盘上的数据结构,它们包含着对数据表里所有记录的引用指针。因此创建索引需要耗费内存空间
2.创建索引和维护索引需要耗费时间,并且随着数据量的增长耗费越来越大
3.对表中的数据删改的时候,索引页需要动态 的进行维护,这样降低了数据的维护速度
2.再谈索引结构
说到索引,现在常用的MySQL数据库,索引的底层实现又是怎样的呢?下面介绍两种树结构
2.1 B-树
B-树是一种多路平衡查找树,多路是指树的分支多与二叉;平衡是指所有叶子结点均在同一层上,以避免出现单支树的情况。
B-树的阶:树中所有结点的孩子的最大值称为B-树的阶,通常用m来表示,从查找效率来考虑,通常取m>=3。
一个m阶B-树的定义如下:
该树或者是空树,或者是满足一下性质 的m叉树。
(1)树中每个结点至多有m个子结点
(2) 除根结点和叶子结点以外,其他每个结点至少有[m/2]个子结点
(3) 若根结点不是叶子结点,则根结点至少有两颗子树
(4) 所有的叶子结点在同一层,可以有[m/2]-1到m-1个关键字,并且叶子结点所在的层数为树的深度
(5)有k个子结点的分支结点恰好包含k-1个关键字
每个结点的一般结构为
n P0 K1 P1 K2 P2…Ki Pi…Kn Pn
其中,n为该结点中的关键字个数;
Pi为指向该子树的指针,并且它所指结点的关键字均大于等于Ki同时小于Ki+1;
Pn所指子树中所有结点的关键字大于等于Kn;
Ki为该结点的关键字,并且应该满足Ki<Ki+1,即关键字是非递减有序的。
2.1.1 B树的查找
基于B树的查找非常类似于二叉排序树的查找,但是每个结点向下查找时,查找的路径不止2条,而是至多为m条。对根结点内有序存放的关键字序列可以用二分查找,也可以用顺序查找或折半查找。
具体如下:
若待查关键字key,根结点内第i个关键字为Ki,则查找分为以下几种情况:
(1)若key=Ki,则查找成功;
(2)若key<Ki,则沿P0所指的子树继续查找;
(3)若Ki<key<Ki+1,则沿指针Pi所指的子树继续查找;
(4)若key>Kn,则沿指针Pn所指的子树继续查找;
(5)若直至找到叶子结点且叶子结点中的查找仍不成功,则查找失败;
2.2 B+树
B+树是B树的变种。一颗m阶B+树,在结构上与m阶B树相同,但在结构内部的关键字安排不同。具体如下:
(1)具有n颗子树的结点含n个关键字,及每个关键字对应一棵子树
(2)结点内关键字仍然按序排列,与B树相同
(3)关键字Ki是 它所对应的子树的根结点中的最大或最小关键字
(4)关键字符合二叉排序树要求,对同一结点内的任意两个关键字Ki和 Kj,若Ki<Kj,则Ki小于Kj对应的子树中的所有关键字,与二叉排序树及B树类似
(5)所有叶子结点中包含了所有的关键字
(6)叶子结点中的关键字对应的子树,实际应用中一般代表记录块。关键字Ki是它所代表的记录块中的最大或最小关键字
(7)各叶子结点可以按关键字大小次序链接在一起,形成单链表,并设设置链头指针
可以看出,在B+树中,所有的关键字都出现在叶子结点中,上面各层结点中的关键字均是下一层相应结点中最大关键字的复写(也可以采用最小关键字复写)。B+树的构造是由上而下的,m限定了结点的大小,自底向上把每个结点的最大关键字或最小关键字复写到上一层结点中。一般可以不画叶子结点的链接情况。
B+树有两种查找操作:一种是从最小关键字起顺序查找,另一种是从根结点开始进行随机查找
在B+树上查找时,若非终端结点上的关键字值等于给定值,并不终止查找过程,而是继续向下查找直至叶子结点。因此,在B+树中,不管查找成功与否,每次查找都是走了一条从根到叶子结点的完整路径
3.如何抉择索引结构
首先,在此申明一个概念,判断索引的标准是什么?是IO渐进复杂度,即IO执行次数 #800000
存放数据的数据结构有很多种,列如二叉树、红黑树…等等,那么我们为什么去选择B+树?
3.1 二叉树
如果二叉树存放的数据是类似于1,2,3,4,5,6,…这样的
二叉树是线性增加的,而且每个结点只能放一个数据,每查询一个数据,就会从头到尾执行,如果查询一次算一次IO的话,那么这个量也是递增的,显然不合理
3.2 红黑树
虽然高度减少了,但是高度仍然是不可控的,IO执行次仍然过多
3.3 B Tree
B Tree是一个绝对平衡树,所有的叶子结点在同一高度
B Tree有什么优势,又是怎么去解决一些问题的的?
先看定义,上图为一个2-3树(每个节点存储2个关键字,有3路),多路平衡查找树也就是多叉的意思,从上图中可以看出,每个节点保存的关键字的个数和路数关系为:
关键字个数 = 路数 – 1
假设要从上图中去寻找id = 28的数据,B Tree 搜索过程如下:
首先把根节点加载进内存,加载了17,35两个关键字,判断规则在上已经谈过了,根据这种规则命中28后,接下来就是加载28对应的数据,就去找28对应的数据区,数据区中存储的是具体的数据或者是指向数据的指针
因为所有的叶子结点在同一层,降低了树的高度,并且子结点中存储的关键字并不止一个,所以降低了IO执行次数。
因此,B Tree很好的利用了操作系统和磁盘的交互特性,解决了这个问题
4.为何选择B+Tree
在上面已经谈过了利用B Tree可以极大的减少与磁盘的交互,那么为什么还要选择B+Tree这个结构呢?