回表

    科技2025-05-20  35

    回表

    1. 回表

    简单说就是mysql内部需要经过两次查询,第一次先索引扫描,然后再通过主键去取索引中未能提供的数据。

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

    怎么避免回表? 将需要的字段放在索引中去。查询的时候就能避免回表。但是不要刻意去避免回表,那样代价太了。也不是将所有的字段都放在所有中。

    实例

    create `table` tb_name( `id` int(11) not null auto_increment , `k` int(11) default '0' , `name` varchar(16), primary key(id) index (k) )engine=InnoDB;

    我们提取id=500这一行的全部数据,这里通过主键id定位到这一行,然后返回数据

    select * from T where ID=500; +-----+---+-------+ | id | k | name | +-----+---+-------+ | 500 | 5 | name5 | +-----+---+-------+

    这里我们先通过普通索引,搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程即为回表。

    select * from T where k=5; +-----+---+-------+ | id | k | name | +-----+---+-------+ | 500 | 5 | name5 | +-----+---+-------+

    2.术语解释:

    主键索引树(B+树)的叶子节点直接就是我们要查询的整行数据,而非主键索引的叶子节点是主键的值,查到主键的值以后,还需要再通过主键的值再进行一次查询。

    问题来了,刚才我们知道了主键索引查询只会查一次,而非主键索引需要回表查询多次。那么,非主键索引一定会查询多次吗? 这就轮到我们的覆盖索引登场了~~

    覆盖索引 覆盖索引(covering index)指一个查询语句的执行结果只用从索引中就能够取得,不必从数据表中读取。也可以称之为实现了索引覆盖。 当一条查询语句符合覆盖索引条件时,MySQL只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后再返回表操作,减少I/O提高效率。 如,表covering_index_sample中有一个普通索引 idx_key1_key2(key1,key2)。 当我们通过SQL语句:select key2 from covering_index_sample where key1 = ‘keytest’;的时候,就可以通过覆盖索引查询,无需回表。

    3.怎么判定是否出现了回表

    Extra中看到了Using where,代表是按照where条件进行了过滤,和是否走索引、回表无必然的关系。Extra中是using index & using where,表示select的数据在索引中能找到,但需要根据where条件过滤,这种情况也不回表。只有在使用了索引,且Extra是Using where的情况下,才代表回表查询数据

    摘自:https://blog.csdn.net/xjh163/article/details/100076904

    Processed: 0.009, SQL: 8