Java 杂谈程序员高性能MySQL

MySQL中的索引(二)InnoDB中的索引

2018-09-02  本文已影响113人  Coding小聪

相关的数据结构

在InnoDB存储引擎中,建立索引所使用的数据结构是B+树。这里我们看看和B+树相关的数据结构。

二叉树

我们把最多能有2个子节点的树称为二叉树。


二叉树

二叉树的分类

B-树

B-树是一种多路平衡查找树。如果它的每一个节点最多包含k个子节点,k被称为树的阶。

其定义很复杂,阶为M的B-树的定义如下:

下面给出两个B-Tree的图,我们可以直观地感受一下:


B-Tree示例1

B+树

在B树的基础上, B+树做了如下改进

高度为2的B+树

根据上面B+树的图,我们可以得到以下信息:

  1. 该B+树的高度为2;
  2. 每个叶子节点中有4条记录;
  3. 叶子节点由大到小串联起来;
  4. 扇出(fanout)数为5。

扇出 是每个索引节点(Non-LeafPage)指向每个叶子节点(LeafPage)的指针

B+树需要保持其自身的平衡,所以在对其进行插入或删除的时候,可能会进行旋转或拆分页以达到平衡。

聚集索引和二级索引

在InnoDB存储引擎中,表都是根据主键的顺序进行存放的,我们将这种存储方式称之为索引组织表

InnoDB表的主键

InnoDB存储引擎的表中,都会存在一个主键,如果在建表时没有指定主键,InnoDB会隐式地创建一个主键。InnoDB主键创建的规则如下:

  1. 如果建表时定义了主键,则用指定的主键;
  2. 如果表没有定义主键,且存在非空unique列,则选择第一个非空unique列为主键;
  3. 如果表即没有指定主键又不存在非空unique列,则InnoDB会创建一个6字节隐藏的row-id作为主键。

数据准备

表
t(id PK, name KEY, sex, flag); 
数据
1, shenjian, m, A  
3, zhangsan, m, A  
5, lisi, m, A  
9, wangwu, f, B 

聚集索引

聚集索引即为主键索引,它是按照每张表的主键构造的一颗B+树,该B+树的叶子节点中存放的是整行记录的数据。由于聚集索引是按照主键的顺序进行排列,所以一张表中只能有一个聚集索引。
针对上面的表t,其聚集索引所对应的B+树如下所示:

聚集索引

辅助索引

辅助索引(secondary index)底层存储使用的数据结构也是B+树,它和聚集索引的区别是:辅助索引的叶子节点不包含整行记录,而是创建辅助索引的列值和一个书签(书签可以理解成指针,) 。辅助索引的存在并不会影响聚集索引,所以一张表上可以有多个非聚集的辅助索引(secondary index)。
如果在表t中的name列创建一个索引,其secondary index所对应的B+树如下图所示:

辅助索引

辅助索引的查询

当通过辅助索引来查询数据时,InnoDB存储引擎会遍历辅助索引并通过叶子节点获取指向主键索引的主键,然后再通过主键索引去找寻完整的行记录。对于上面的例子,如果我们select * from t where name=‘lisi’;

辅助索引中的查找
我们可以看到本次查找一共进行了6次IO操作(辅助索引中3次+聚集索引中3次)。从这里我们可以知道使用辅助索引进行查找为啥要比聚集索引慢的原因了。
这里有一点需要注意,B+树索引并不能找到一个给定键值的具体行,它能找到的是被查找行所在的页,接着数据库会把页读入到内存,再在内存中进行数据所在行的查找。一般而言,页的大小为16K,一个页中能存放的记录数=16K/行的大小,对于上面的图示的聚集索引和辅助索引我们假设一个页中只存一条记录。

参考
1分钟了解MyISAM与InnoDB的索引差异.58沈剑

上一篇 下一篇

猜你喜欢

热点阅读