二级索引与回表

参考:https://www.cnblogs.com/mellowsmile/p/4708333.html

什么是回表?

简单来说就是数据库根据索引找到了指定的记录所在行后,还需要根据rowid再次到数据块里取数据的操作。(索引中不包含要查询的字段,就需要再次根据rowid或者主键id到数据行中取查询字段,即为回表)
比如这样的执行计划,先索引扫描,再通过rowid去取索引中未能提供的数据,即为回表。
“回表”一般就是指执行计划里显示的“TABLE ACCESS BY INDEX ROWID”。
再例如,虽然只查询索引里的列,但是需要回表过滤掉其他行。

mysql为例,mysql一般使用Innodb引擎。建表时,主键会自动创建聚簇索引,聚簇索引会把索引字段和数据行放在一起,这样根据该字段查询出的数据可以直接取想要的列,不需要回表。

一个表只能创建一个聚簇索引,因此聚簇索引应该用于唯一且查询最频繁的字段。

非聚簇索引即为二级索引,二级索引存储的是索引字段和对应的主键(oracle为rowid)。当根据二级索引查询时,查询列不包含在索引中时,就需要先根据索引查询出对应的id,然后再根据id查询数据行,取查询列,这里就多一次回表。

innodb中,在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引,辅助索引叶子节点存储的不再是行的物理位置,而是主键值

索引的意义

索引最直接的意义就是为了提高查询效率,因此需要让根据索引查询出的数据越少越好,例如唯一字段。

如果根据索引查询出很多重复数据,那么这个索引本身就不再具备高查询效率。

另外普通索引一般为b-tree索引,使用二分查找,当数据库认为根据索引查询出的数据大概超过全表的30%时,数据库就会认为该索引的查询效率不如全表查询,就会废弃使用该索引,而换使用全表查询,因为根据索引查询出的数据还要再进行一次回表,即多了一次IO操作,总的执行效率不一定比全表查询更快。

原文地址:https://www.cnblogs.com/flysand/p/10718584.html