面试官:小伙子,你给我说一下你对MySQL索引的理解吧

1、索引是什么?

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

2、索引能干什么?

索引很是关键,尤为是当表中的数据量愈来愈大时,索引对于性能的影响愈发重要。索引可以轻易将查询性能提升好几个数量级,总的来讲就是能够明显的提升查询效率。sql

3、索引的分类?

一、从存储结构上来划分:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。这里所描述的是索引存储时保存的形式,数据库

二、从应用层次来分:普通索引,惟一索引,复合索引数据结构

三、根据中数据的物理顺序与键值的逻辑(索引)顺序关系:汇集索引,非汇集索引。性能

平时讲的索引类型通常是指在应用层次的划分。spa

就像手机分类:安卓手机,IOS手机 与 华为手机,苹果手机,OPPO手机同样。3d

普通索引:即一个索引只包含单个列,一个表能够有多个单列索引指针

惟一索引:索引列的值必须惟一,但容许有空值code

复合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并blog

聚簇索引(汇集索引):并非一种单独的索引类型,而是一种数据存储方式。具体细节取决于不一样的实现,InnoDB的聚簇索引其实就是在同一个结构中保存了B-Tree索引(技术上来讲是B+Tree)和数据行。

非聚簇索引:不是聚簇索引,就是非聚簇索引

4、索引的底层实现

mysql默认存储引擎innodb只显式支持B-Tree( 从技术上来讲是B+Tree)索引,对于频繁访问的表,innodb会透明创建自适应hash索引,即在B树索引基础上创建hash索引,能够显著提升查找效率,对于客户端是透明的,不可控制的,隐式的。

不谈存储引擎,只讨论实现(抽象)

4.一、Hash索引

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

4.二、B-Tree索引(MySQL使用B+Tree)

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

4.三、B+Tree索引

是B-Tree的改进版本,同时也是数据库索引索引所采用的存储结构。数据都在叶子节点上,而且增长了顺序访问指针,每一个叶子节点都指向相邻的叶子节点的地址。相比B-Tree来讲,进行范围查找时只须要查找两个节点,进行遍历便可。而B-Tree须要获取全部节点,相比之下B+Tree效率更高。

结合存储引擎来讨论(通常默认使用B+Tree)

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

id name birthday
1 Tom 1996-01-01
2 Jann 1996-01-04
3 Ray 1996-01-08
4 Michael 1996-01-10
5 Jack 1996-01-13
6 Steven 1996-01-23
7 Lily 1996-01-25

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

在InnoDB中的实现

5、为何索引结构默认使用B+Tree,而不是Hash,二叉树,红黑树?

B-tree:由于B树无论叶子节点仍是非叶子节点,都会保存数据,这样致使在非叶子节点中能保存的指针数量变少(有些资料也称为扇出),指针少的状况下要保存大量数据,只能增长树的高度,致使IO操做变多,查询性能变低;

Hash:虽然能够快速定位,可是没有顺序,IO复杂度高。

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

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

6、为何官方建议使用自增加主键做为索引?

结合B+Tree的特色,自增主键是连续的,在插入过程当中尽可能减小页分裂,即便要进行页分裂,也只会分裂不多一部分。而且能减小数据的移动,每次插入都是插入到最后。总之就是减小分裂和移动的频率。

6.一、插入连续的数据:

6.二、插入非连续的数据:

7、简单总结下

一、MySQL使用B+Tree做为索引数据结构。

二、B+Tree在新增数据时,会根据索引指定列的值对旧的B+Tree作调整。三、从物理存储结构上说,B-Tree和B+Tree都以页(4K)来划分节点的大小,可是因为B+Tree中中间节点不存储数据,所以B+Tree可以在一样大小的节点中,存储更多的key,提升查找效率。四、影响MySQL查找性能的主要仍是磁盘IO次数,大部分是磁头移动到指定磁道的时间花费。五、MyISAM存储引擎下索引和数据存储是分离的,InnoDB索引和数据存储在一块儿。六、InnoDB存储引擎下索引的实现,(辅助索引)所有是依赖于主索引创建的(辅助索引中叶子结点存储的并非数据的地址,仍是主索引的值,所以,全部依赖于辅助索引的都是先根据辅助索引查到主索引,再根据主索引查数据的地址)。

八、因为InnoDB索引的特性,所以若是主索引不是自增的(id做主键),那么每次插入新的数据,都极可能对B+Tree的主索引进行重整,影响性能。所以,尽可能以自增id做为InnoDB的主索引。

相关文章
相关标签/搜索