MySQL的覆盖索引
MySQL的覆盖索引
前言
当一个索引包含了查询所需的全部字段时,就可以提高查询效率,这样的索引又被称之为覆盖索引。
以MySQL常见的三种存储引擎为例:InnoDB、MyISAM、Memory,对于覆盖索引提高查询效率的方式均不同,
下面让我们分别讲讲:
InnoDB
在InnoDB中,主键索引的叶子节点存储完整的数据行,称为聚簇索引,而唯一索引、普通索引、联合索引的叶子节点只存储索引字段和主键值,称之为二级索引。
当一条查询sql用到的索引只包含部分需要的字段时,就需要先在二级索引中查到相应数据的主键字段,然后根据主键字段在主键索引中查到全部数据。回到主键索引中查询数据,这个就叫做回表,因为一次索引查询还查不到全部数据,还需要回表一次才能查到全部数据。
但是,如果sql查询所需的字段全部包含在用到的索引中,就可以在二级索引中直接查询到所需的全部数据,不需要再回表了,这种包含所需的全部字段的索引,就叫做覆盖索引。
在InnoDB中,覆盖索引可以减少回表的次数,提高查询效率。
MyISAM
在MyISAM中,索引保存的是数据值,以及指向数据在磁盘中位置的指针。
当一条sql查询没有用到索引时,就需要直接到磁盘中的数据文件进行搜索。
当一条sql查询用到索引的部分字段时,会先在索引中查到部分字段的指针,然后再到磁盘中根据指针查询到对应行,再在行中查询全部所需数据。
但是,如果sql查询用到的索引包含全部所需的字段时,也就是用到覆盖索引时,就可以直接在索引中查到全部所需字段的值,不需要再进行磁盘IO。
在MyISAM中,覆盖索引可以减少磁盘IO的次数,提高查询效率。
Memory
在Memory中,与在MyISAM中逻辑相似,不过Memory是将数据存储在内存中,虽然内存IO比磁盘IO快很多,但使用覆盖索引仍有利于减少内存IO,提高查询效率。
需要注意的是,本文并未特别考虑同时使用其它索引的情况,不使用覆盖索引而使用其它索引仍然可能达到同样的效果。