噢,他明确了,河水既没有牛伯伯说的那么浅,也没有小松鼠说的那么深,只有本人亲自试过才晓得。

看了很多对于索引的博客,讲的大同小异。然而始终没有让我明确对于索引的一些概念,如B-Tree索引,Hash索引,惟一索引….或者有很多人和我一样,没搞清楚概念就开始钻研B-Tree,B+Tree等构造,导致在面试的时候答非所问!

索引是什么?

索引是帮忙MySQL高效获取数据的数据结构。

索引能干什么?

进步数据查问的效率。

索引:排好序的疾速查找数据结构!索引会影响where前面的查找,和order by 前面的排序。

一、索引的分类

1. 从存储构造上来划分:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。

2. 从利用档次来分:一般索引,惟一索引,复合索引。

3. 依据中数据的物理程序与键值的逻辑(索引)程序关系:汇集索引,非汇集索引。

1 中所形容的是索引存储时保留的模式,2 是索引应用过程中进行的分类,两者是不同档次上的划分。不过平时讲的索引类型个别是指在利用档次的划分。

就像手机分类,安卓手机,IOS手机 与 华为手机,苹果手机,OPPO手机一样。

  • 一般索引:即一个索引只蕴含单个列,一个表能够有多个单列索引
  • 惟一索引:索引列的值必须惟一,但容许有空值
  • 复合索引:即一个索引蕴含多个列
  • 聚簇索引(汇集索引):并不是一种独自的索引类型,而是一种数据存储形式。具体细节取决于不同的实现,InnoDB的聚簇索引其实就是在同一个构造中保留了B-Tree索引(技术上来说是B+Tree)和数据行。
  • 非聚簇索引:不是聚簇索引,就是非聚簇索引(认真脸)。

二、索引的底层实现

mysql默认存储引擎innodb只显式反对B-Tree( 从技术上来说是B+Tree)索引,对于频繁拜访的表,innodb会通明建设自适应hash索引,即在B树索引根底上建设hash索引,能够显著进步查找效率,对于客户端是通明的,不可管制的,隐式的。

不谈存储引擎,只探讨实现(形象)

Hash索引

基于哈希表实现,只有准确匹配索引所有列的查问才无效,对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),并且Hash索引将所有的哈希码存储在索引中,同时在索引表中保留指向每个数据行的指针。

B-Tree能放慢数据的访问速度,因为存储引擎不再须要进行全表扫描来获取数据,数据分布在各个节点之中。

是B-Tree的改良版本,同时也是数据库索引索引所采纳的存储构造。数据都在叶子节点上,并且减少了程序拜访指针,每个叶子节点都指向相邻的叶子节点的地址。相比B-Tree来说,进行范畴查找时只须要查找两个节点,进行遍历即可。而B-Tree须要获取所有节点,相比之下B+Tree效率更高。

案例:假如有一张学生表,id为主键

在MyISAM引擎中的实现(二级索引也是这样实现的)

在InnoDB中的实现

三、问题

问:为什么索引构造默认应用B-Tree,而不是hash,二叉树,红黑树?

hash:尽管能够疾速定位,然而没有程序,IO复杂度高。

二叉树:树的高度不平均,不能自均衡,查找效率跟数据无关(树的高度),并且IO代价高。

红黑树:树的高度随着数据量减少而减少,IO代价高。

问:为什么官网倡议应用自增长主键作为索引。

联合B+Tree的特点,自增主键是间断的,在插入过程中尽量减少页决裂,即便要进行页决裂,也只会决裂很少一部分。并且能缩小数据的挪动,每次插入都是插入到最初。总之就是缩小决裂和挪动的频率。

插入间断的数据:

插入非间断的数据: