回表查询是数据库查询中的一种现象,它发生在索引包含的数据不足以满足查询需求时。
在数据库中,尤其是使用InnoDB存储引擎的MySQL数据库,索引分为聚集索引(clustered index)和普通索引(secondary index)。聚集索引的叶子节点存储的是完整的数据行,而普通索引的叶子节点存储的是该行数据的主键值。当进行查询时,如果使用了普通索引,且查询所需的字段不全都包含在索引中,数据库就需要通过索引找到对应的主键值,然后再通过主键值到聚集索引中查找完整的数据行,这个过程就是所谓的“回表查询”。具体来说:
- 索引扫描:数据库首先通过普通索引快速定位到符合条件的记录的主键值。
- 回表操作:然后,数据库使用这些主键值回到聚集索引中查找对应的完整数据行。
- 性能影响:由于需要两次访问索引(一次普通索引,一次聚集索引),这会增加I/O操作和CPU负载,从而降低查询性能。
总的来说,了解回表查询的概念对于优化数据库性能是非常重要的,开发者在设计索引和编写查询语句时应该尽量避免不必要的回表操作,以提高查询效率。
举例
现有User表 字段为 ID(主键),name,age
以name这一列创建索引(以name列数据,经过b+tree算法形成b+tree,存储到硬盘)
此时name列的B+树存储的数据为当前列数据(name这一列)和主键列数据(id)
当执行select * form user while name = ? 时 命中name列的B+树
但我们要查询全部数据,此时这棵树存储的数据不是完整的,所以就要通过回表查询获取完整的数据