浅谈数据库索引
1 概述
索引(index)是帮助mysql高效获取数据的数据结构,以某种方式引用(指向)数据,这样就可以实现高级查找算法。
图1为数据表,一共有两列七条数据,最左边的是数据记录的物理地址(在逻辑上相邻的记录在磁盘上并不一定是物理相邻的)。为了加快Col2的查找,可以维护一个图2所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找快速获取相应的数据。
2 优劣势
优势:
- 提高数据检索的效率,降低数据库的IO成本。
- 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。
劣势:
- 索引实际上也是一张表,需要占用磁盘空间。
- 虽然提高了查询效率,但同时也降低更新表的速度,例如 INSERT, UPDATE, DELETE。因为更新表时,不仅要保存数据,还需要保存更新的索引信息。
3 索引结构
索引是在mysql的存储引擎层中实现的,所以每种存储引擎的所以不一定完全相同,也不是所有的存储引擎都支持所有的索引类型的。mysql目前提供了4种索引:
- B-tree 索引:InnoDB, MyISAM, Memory 引擎支持。
- HASH 索引:Memory引擎支持。
- R-tree 索引(空间索引):MyISAM引擎支持。
- Full-text(全文索引):InnoDB 5.6版本之后,MyISAM引擎支持。
3.1 B-tree 结构
B-tree又叫多路平衡搜索树,特性如下(m叉):
- 每个节点最多包含m个孩子
- 除根节点和叶子节点外,每个节点至少有 cell(m/2) 个孩子
- 若根节点不是叶子节点,则至少有两个孩子
- 所有的叶子节点都在同一层
- 每个非叶子节点由 n 个key 和 n+1 个指针组成,其中 ceil(m/2)-1 <= n <= m-1
例如,m=5,2 <= n <= 4,当n>4时,中间节点分裂到父节点,两边节点分裂。
以插入数据 C N G A H E K Q M F W L T Z D P R X Y S 为例:
- 插入前 4 个字母 C N G A
- 插入 H:n>4,中间元素 G 向上分离到新的节点
- 插入 E K Q
- 插入 M:中间元素 M 向上分裂到父节点 G
……
最后:
B树 和 二叉树 相比:查询效率更高,因为对于相同的数据量,B树的层级结构比二叉树小,因此搜索速度快。
3.2 B+树 结构
B+树是B树的变种,区别是:
- n叉的B+树最多含有n个key,而B树最多含有n-1个key
- B+树只有叶子节点保存所有的key信息,查询任何key都要从根走到叶子节点,所以查询效率更稳定
- B+树所有的非叶子节点都可以看作是key的索引部分
3.3 MySQL中的B+树
对经典的B+树进行了优化:增加了一个指向相邻叶子节点的链表指针,因此形成了带有顺序指针的B+树,提高了区间访问的性能。
MySQL中的B+树结构示意图: