Hash索引是MEMORY引擎默认使用的索引结构,也只有MEMORY引擎能够显式使用Hash索引,实际上就是HashTable,key-value结构。同时也是用拉链法解决hash冲突,这里不展开讨论。html
这里须要注意的是HashTable的Value里面并非直接存储的单行数据而是存的是指针。mysql
若是咱们要了解B+树,就必定要先了解B树,B树是为磁盘等直接存储的辅助存储设备而设计的一种平衡搜索树,它的节点能够存储多个关键字,而且它是一个多叉树,一个B树知足如下条件:算法
先解释几个词:sql
定义:数据库
如图这是一个3阶B树 markdown
B树的插入主要涉及三个步骤,查询、插入、分裂。数据结构
B树的删除其实和插入很是类似,只是更加复杂一点,由于删除能够从任意节点删除,而并不是只能从叶子节点删除。因此就涉及到删除后保持结构定义的过程。这里就再也不赘述删除具体的流程,比较复杂。建议你们去看一下《算法导论》286页,有详细的描述。oop
这里能够看到 Max. Degree = 3 表示是一个三阶B树,因此他的关键字最多只能有三个。性能
这时候若是咱们再插入1,就会发现,结构并不会恢复成以前的样子。 动画
其实从刚刚的插入删除的演示中就已经能够看出查询的过程,搜索一颗B树和搜索一颗二叉搜索树相似,不一样的就在于每一个节点的分支选择是多叉的,而不必定是二叉。
为了探究这个问题咱们首先应该了解几个知识
索引就是一种数据结构,须要存储,而且索引也不仅仅在内存中,须要存储到磁盘中。
在我以前的博文中提到过,实际上数据库查询数据是先查主存,若是不存在,才去磁盘中查询,而后带到主存里来。这里在磁盘查询的过程当中会涉及到磁盘的io,实际上若是不考虑从主存中查询,最影响数据库查询速度的就是磁盘IO,所以尽可能减小磁盘IO就能够显著的提高数据的查询速度。
传统的磁盘读取依靠的是机械运动,IO的耗时就分为寻道时间、旋转延迟、传输时间三个部分。**SSD则不一样。**为了减小io的消耗,采用来预读的机制。当访问一个地址数据的时候,与其相邻的数据很快也会被访问到。每次磁盘IO读取的数据咱们称之为一页(page)。一页的大小与操做系统有关,通常为4k或者8k。这也就意味着读取一页内数据的时候,实际上发生了一次磁盘IO。
经过上面几点,咱们就能够知道,索引会写盘,查询索引的过程就是查询节点的过程若是不在内存中就会去查找磁盘,产生磁盘IO,那么索引的查询速度大部分就取决于每次查询须要访问的数据页。咱们能够假设一棵 100 万节点的平衡二叉树,树高 20。一次查询可能须要访问 20 个数据块。而若是使用b树的话就取决于咱们N叉树的N的大小。固然,这里B+树也是同理的。
B+树其实就是B树和顺序索引访问方法演化而来的,在这里就不赘述B树和B+树的区别了,你们只要知道B树的每一个结点都存储了key和data,B+树的data存储在叶子节点上。
B+树其实就是B树的变体,和B树很类似。如图是一个三阶B+树。
从图中咱们能够和清楚的看到,实际上B+树的插入和删除的过程和B树基本一致,惟一区别是,B+树经过一个双向链表把叶子节点连接起来,在维护树的时候一样须要维护这个双向链表,这里也不仔细去说详细的插入删除的算法。详见《Mysql技术内幕 InnoDB存储引擎》 P202
查询过程其实也是接近的,区别只是B+树的节点没有存储data,因此其实是查到链表中。
非叶子节点不存储数据就意味着存放一样多的key, 树的层高能进一步被压缩, 使得检索的时间更短。而且叶子结点是链表形式,能更快的进行顺序遍历。
也就是主键索引,叶子节点存储的是整行的数据,而且数据也是依据主键索引进行排序,主键索引一张表只能有一个也是由于数据只能按照一个索引进行排序。聚簇索引附带惟一性约束。
也叫辅助索引,叶子节点并不存放整行数据,而是存储主键的值。要查找到完整数据须要回表。
用来确保表中没有两个数据行具备彻底相同的键值通常咱们使用它来帮助维护数据完整性。同时须要注意惟一性约束不等于惟一索引。
普通索引,用来辅助查询,不具有惟一性约束。
索引按照顺序递增(不必定要连续,只要是递增就行),索引紧凑;随机插入为了保证索引的顺序行可能会形成索引的数据页分裂。数据页的分裂就产生数据空洞。分裂过程不只影响性能还会影响空间使用率,由于本来一个数据页的数据,分红了两个数据页。 固然有分裂就有合并。当相邻两个页因为删除了数据,利用率很低以后,会将数据页作合并。合并的过程,能够认为是分裂过程的逆过程。
这里引用一张《Mysql 45讲》中的图
非聚簇索引查询到主键,回到聚簇索引搜索的过程,咱们称为回表。
覆盖索引并非一种索引类型,而是从非聚簇索引中就能够查询到的结果不用,再去回表。这种操做能够的好处是,非聚簇索引只存储索引值,并无整行的数据,故其大小远小于聚簇索引,能够减小大量的io操做,因此咱们常说不要用select *。
联合索引是指对表上的多个列进行索引,联合索引也是一棵B+树,不一样的是联合索引的键值数量不是1,而是大于等于2。 这里须要注意的是联合索引的结构 联合索引的全部索引列都出如今索引树上,并依次比较三列的大小进行排序。
做者水平有限,如有错误遗漏,请指出。
参考文章
5.MySQL技术内幕 InnoDB存储引擎 第2版