索引基础(持续更新中)

164 阅读3分钟

B树

很多存储引擎使用的时B-Tree,即每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。

底层的存储引擎可能使用不同的存储结构。存储引擎以不同的方式使用B-Tree索引,性能也各不相同,各有优劣。

B-Tree

B+Tree

B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。

MyISAM使用前缀压缩技术使得索引更小,但是InnoDB则按照元数据格式进行存储。

MyISAM索引通过数据的物理位置引用被索引的行,而InnoDB则根据主键引用被索引的行。

索引对多个值进行排序的依据是CREAT TABLE语句中定义索引时列的顺序。

B+Tree对索引列时顺序组织存储的,所以很适合查找范围数据。

可以使用B+Tree索引的查询类型

B+Tree索引适用于全键值、键值范围或键前缀查找。其中键前缀查找只适用于根据最左前缀的查找

  • 全值匹配
  • 匹配最左前缀
  • 匹配列前缀
  • 精确匹配某一列并范围匹配另外一列
  • 只访问索引的查询:查询只需要访问索引,无需访问数据行。

B+Tree索引的限制:

  • 若不是按照索引的最左列开始查询找,则无法使用索引;
  • 不能跳过索引中的列;
  • 如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找。

有些限制并不是B+Tree本身导致的,而是MySQL优化器和存储引擎使用的索引的方式导致的。

为什么使用 B+Tree

  1. B+Tree更适合外部存储,由于内节点无 data 域,一个结点可以存储更多的内结点,每个节点能索引的范围更大更精确,也意味着B+Tree单次磁盘IO的信息量大于B-Tree,I/O效率更高。

  2. Mysql是一种关系型数据库,区间访问是常见的一种情况,B+Tree叶节点增加的链指针,加强了区间访问性,可使用在范围区间查询等,而B-Tree每个节点 key 和 data 在一起,则无法区间查找。

  3. B-Tree的非叶子结点会存放数据,而B+Tree的非叶子结点不存放数据,只存放关键字,这样同一个结点,B+Tree的结点能形成的叉数越多,那么存储一定数量的数据,B+Tree的高度越小,那么插入、查找、删除的性能会越高。(B-TreeB+Tree的插入、查找、删除的时间复杂度与树的高度成正相关)。

MySQL 中 Innodb 存储引擎存储数据的最小单元是页,一页的大小默认是 16KB(可修改)

MariaDB [(none)]> show variables like 'innodb_page_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
1 row in set (0.001 sec)

在读数据时,也是以页为单位将数据从磁盘加载进内存当中,每从磁盘中读取一个页,就会发生一次磁盘 IO。也就是说,在查找数据时,每遍历一个结点,就意味着读取一个数据页,也就是发生一次 IO。

参考

[1] 数据结构动态展示 www.cs.usfca.edu/~galles/vis…

[2] 以B tree和B+ tree的区别来分析mysql索引实现 www.jianshu.com/p/0371c9569…

[3] 由 B-/B+树看 MySQL索引结构 segmentfault.com/a/119000000…