1.索引的本质

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

索引存储在文件里(硬盘里)
索引结构

  • 二叉树(红黑树)
  • HASH
  • BTREE

    磁盘存取原理
  • 寻道时间(速度慢,费时)
  • 旋转时间(速度较快)
    一次I/O

2.B-Tree

  • 度(Degree)–节点的数据存储个数
  • 叶节点具有相同的深度
  • 叶节点的指针为空
  • 节点中的数据key从左到右递增排序
B-树是一种多路搜索树(并不一定是二叉的)

1970年,R.Bayer和E.mccreight提出了一种适用于外查找的树,它是一种平衡的多叉树,称为B树(或B-树、B_树)。
一棵m阶B树(balanced tree of order m)是一棵平衡的m路搜索树。

它或者是空树,或者是满足下列性质的树:

  1. 根结点至少有两个子女;
  2. 每个非根节点所包含的关键字个数 j 满足:┌m/2┐ - 1 <= j <= m - 1;
  3. 除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树个数 k 满足:┌m/2┐ <= k <= m ;
  4. 所有的叶子结点都位于同一层。
特点:

是一种多路搜索树(并不是二叉的):

  1. 定义任意非叶子结点最多只有M个儿子;且M>2;
  2. 根结点的儿子数为[2, M];
  3. 除根结点以外的非叶子结点的儿子数为[M/2, M];
  4. 每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
  5. 非叶子结点的关键字个数=指向儿子的指针个数-1;
  6. 非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
  7. 非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的
    子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
  8. 所有叶子结点位于同一层;
    如:(M=3)

3.B+Tree(B-Tree变种)

  • 非叶节点不存储data,只存储key,可以增大度
  • 叶子节点不存储指针
  • 叶子节点多了横向指针顺序访问指针,可范围查找,提高区间访问的性能

B+树是应文件系统所需而出的一种B-树的变型树。

一棵m阶的B+树和m阶的B-树的差异在于:
  1. 有n棵子树的结点中含有n个关键字,每个关键字不保存数据,只用来索引,所有数据都保存在叶子节点。
  2. 所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
  3. 所有的非终端结点可以看成是索引部分,结点中仅含其子树(根结点)中的最大(或最小)关键字。
    通常在B+树上有两个头指针,一个指向根结点,一个指向关键字最小的叶子结点。
B+树是B-树的变体,也是一种多路搜索树:
  1. 其定义基本与B-树同,除了:
  2. 非叶子结点的子树指针与关键字个数相同;
  3. 非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树
    (B-树是开区间);
  4. 为所有叶子结点增加一个链指针;
  5. 所有关键字都在叶子结点出现;
B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;
B+的特性:
  1. 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好
    是有序的;
  2. 不可能在非叶子结点命中;
  3. 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储
    (关键字)数据的数据层;
  4. 更适合文件索引系统;

4.MyISAM索引实现(非聚集)

  • 索引文件和数据文件时分离的(.frm结构文件和.MYD数据文件和.MYI索引文件)
    主键索引与非主键索引无区别:

5.InnoDB索引实现(聚集)

  • 数据文件本身就是B+Tree组织的一个索引结构文件(.frm结构文件和.idb数据和索引文件)
  • 聚集索引-叶节点包含了完整的数据记录
  • 为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
    数据文件本身就是B+Tree组织的一个索引结构文件,主键索引就是聚集索引,不建默认自动建索引。用字符串不如整型比较快,字符串需要先转成ASCII,整型省空间,int占32位。不可用UUID,因为UUID不一定自增,可能造成B+Tree分裂。
  • 为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

主键索引与非主键索引有区别:

聚集索引通常就是主键索引

addUniqueConstraint 和索引 索引degree_主键


辅助索引就是非聚集索引,只包含索引列和一个用于查找对应行记录的『书签』

addUniqueConstraint 和索引 索引degree_结点_02


B+Tree节点中关键字冗余问题?

为什么mysql页文件默认16K?

6.InnoDB索引性能分析

  • 一般使用磁盘I/O次数评价索引结构的优劣。
  • 预读:磁盘一般会顺序向后读取一定长度的数据(页的整数倍)放入内存。
  • 局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。
  • B+Tree节点的大小设为等于一个页,每次新建节点直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,就实现了一个节点的载入只需一次I/O.
  • 一般操作系统的最小存储单元为页,1页大小为4K。
  • 查看MySQL文件页大小(16K):SHOW GLOBAL STATUS like ‘Innodb_page_size’