【MySQL技术内幕】26-聚集索引与辅助索引

聚集索引

  • Innodb中每张表都会有一个聚集索引,其行记录存在该索引的叶子节点上。
  • 叶子节点通过双向链表链接,按照主键的顺序排序
  • 页中的记录也是双向链表进行维护,物理上可以不按照顺序存储。
  • 所有索引只能定位到页,不能通过索引定位到具体的行,到页后通过Page Directory确定行。

聚集索引的另一个好处是,它对于主键的排序查找和范围查找速度非常快。叶子节点的数据就是用户所要查询的数据。如用户需要查询一张注册用户的表,查询最后注册的10位用户,由于B+树索引是双向链表的,用户可以快速找到最后一个数据页,并取出10条记录。若用命令 EXPLAIN进行分析,可得:
【MySQL技术内幕】26-聚集索引与辅助索引

可以看到虽然使用 ORDER BY对记录进行排序,但是在实际过程中并没有进行所谓的 filesort操作,而这就是因为聚集索引的特点另一个是范围查询( range query),即如果要查找主键某一范围内的数据,通过叶子节点的上层中间节点就可以得到页的范围,之后直接读取数据页即可,又如:
【MySQL技术内幕】26-聚集索引与辅助索引

执行 EXPLAIN得到了 MySQL数据库的执行计划( execute plan),并且在rows列中给出了一个查询结果的预估返回行数。要注意的是,rows代表的是一个预估值,不是确切的值。

辅助索引

对于辅助索引( Secondary Index,也称非聚集索引),叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签( bookmark)。该书签用来告诉 InnoDB存储引擎哪里可以找到与索引相对应的行数据。由于 InnoDB存储引擎表是索引组织表,因此 InnoDe存储引擎的辅助索引的书签就是相应行数据的聚集索引键。

辅助索引的存在并不影响数据在聚集索引中的组织,因此每张表上可以有多个辅助索引。当通过辅助索引来寻找数据时, InnoDB存储引擎会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键,然后再通过主键索引来找到个完整的行记录。举例说,如果在一棵高度为3的辅助索引树中查找数据,那需要对这棵辅助索引树遍历3次找到指定主键,如果聚集索引树的高度同样为3,那么还需要对聚集索引树进行3次查找,最终找到一个完整的行数据所在的页,因此一共需要6次逻辑Io访问以得到最终的一个数据页。