噢,他明确了,河水既没有牛伯伯说的那么浅,也没有小松鼠说的那么深,只有本人亲自试过才晓得。
看了很多对于索引的博客,讲的大同小异。然而始终没有让我明确对于索引的一些概念,如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的特点,自增主键是间断的,在插入过程中尽量减少页决裂,即便要进行页决裂,也只会决裂很少一部分。并且能缩小数据的挪动,每次插入都是插入到最初。总之就是缩小决裂和挪动的频率。
插入间断的数据:
插入非间断的数据: