一、覆盖索引
select 的数据列只用从索引中就能够取得,不需要回表进行二次查询,也就是说查询列要被所使用的索引覆盖。对于 innodb 表的二级索引,如果索引能覆盖到查询的列,那么就可以避免对主键索引的二次查询。
不是所有类型的索引都可以成为覆盖索引。覆盖索引要存储索引列的值,而哈希索引、全文索引不存储索引列的值,所以MySQL使用b+树索引做覆盖索引。
对于使用了覆盖索引的查询,在查询前面使用 explain ,输出的extra列会显示为 using index 。
比如 user_like 用户点赞表,组合索引为 (user_id, blog_id) , user_id 和 blog_id 都不为null 。
explain 结果的 Extra 列为 Using index ,查询的列被索引覆盖,并且where筛选条件符合最左前缀原则,通过索引查找就能直接找到符合条件的数据,不需要回表查询数据。
explain select blog_id from user_like where user_id = 13;
explain select user_id from user_like where blog_id = 1;
explain 结果的 Extra 列为 Using where; Using index , 查询的列被索引覆盖,where筛选条件不符合最左前缀原则,无法通过索引查找找到符合条件的数据,但可以通过索引扫描找到符合条件的数据,也不需要回表查询数据。
二、回表
通俗来说
通俗的讲就是,如果select所需获得列中有非索引列,一次索引查询不能获取所有信息,需要到表中找到相应的列的信息。这就叫回表。也就是说,需要从辅助索引(Secondary Index)中获取额外的数据列,需要通过辅助索引回到主键索引(Primary Index)中进行查找。
而如果根据一次索引查询就能获得所有列信息,就不需要回表。
具体定义
当执行一个查询语句,包含了辅助索引的列时,MySQL会首先使用辅助索引定位到符合条件的记录的主键值,然后再根据这些主键值去主键索引查找对应的完整数据行。这个过程就被称为回表。