0
点赞
收藏
分享

微信扫一扫

MySQL的回表查询与索引覆盖

回表查询

InnoDB索引分为两大类,一类是聚集索引(Clustered Index),一类是非聚集索引(Secondary Index)

聚集索引(聚簇索引):叶子节点中存的是整行数据,找到索引也就找到了数据,索引即数据,表中行的物理顺序与键值的逻辑(索引)顺序相同,一个表只能包含一个聚集索引。因为索引(目录)只能按照一种方法进行排序。

非聚集索引(普通索引、非聚簇索引、二级索引):非聚集索引的btree叶子节点中存储的是当行数据的PK(主键)。例如MYISAM通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因。

为什么非主键索引结构叶子结点存储的是主键值?

减少了出现行移动或者数据页分裂时二级索引的维护工作(当数据需要更新的时候,二级索引不需要修改,只需要修改聚簇索引,一个表只能有一个聚簇索引,其他的都是二级索引,这样只需要修改聚簇索引就可以了,不需要重新构建二级索引)

在使用非聚集索引时,为了取到具体数据,则需要通过PK回到聚集索引里去查询数据。着就叫回表查询。扫描了2次索引树。所以效率相对较低。

索引覆盖

索引覆盖就是解决回表查询的一种方案。见名知意,就是查询的所有列均被所使用的索引列覆盖(可以是单列索引也可以是联合索引)。

因为索引中已经包含了要查询的字段的值,因此查询的时候直接返回索引中的字段值就可以了,不需要再到表中查询,避免了对主键索引的二次查询,也就提高了查询的效率。

因为覆盖索引必须要存储索引的列值,而哈希索引、空间索引和全文索引等都不存储索引列值,从而只有使用B-Tree索引的数据可以做覆盖索引。

进行索引覆盖查询时,在explain(执行计划)的Extra列可以看到【Using Index】的信息。

索引覆盖的优点

  1. 索引条目通常远小于数据行的大小,因为覆盖索引只需要读取索引,极大地减少了数据的访问量。
  2. 索引是按照列值顺序存储的,对于IO密集的范围查找会比随机从磁盘读取每一行数据的IO小很多。
  3. 一些存储引擎比如MyISAM在内存中只缓存索引,数据则依赖操作系统来缓存,因此要访问数据的话需要一次系统调用,使用覆盖索引则避免了这一点。
  4. 由于InnoDB的聚簇索引,覆盖索引对InnoDB引擎下的数据库表特别有用。因为InnoDB的二级索引在叶子节点中保存了行的主键值,如果二级索引能够覆盖查询,就避免了对主键索引的二次查询。

哪些场景适合使用索引覆盖来优化SQL

  1. 当不需要查询整行记录时;
  2. 全表count查询优化;
  3. Limit分页查询;

哪些情况下不要建索引

  1. 表记录太少
  2. 经常增删改的表或者字段(如用户余额)
  3. Where条件里用不到的字段不创建索引
  4. 过滤性不好的不适合建索引(如性别)

MySQL的回表查询与索引覆盖_数据库

举报

相关推荐

0 条评论