MySQL 回表查询 性能代价?如何避免?

一、什么是回表查询?

  1. 二级索引只会存储索引和主键,当通过二级索引查找数据时,如果想要找到其他列的数据就会拿着主键去聚簇索引里查询整行数据,这个过程就是回表

二、回表的性能代价?

  1. 回表不只是多了一次查询,而是多了很多次的随机IO操作
  2. 因为二级索引是根据索引的值排序的,二聚簇索引是根据主键的值进行排序的。
  3. 比如查询age=20的人的信息,可能会查到不同无序的id,拿着这些id去聚簇索引查询会定位到不同的数据页,产生大量的随机IO。
  4. 顺序IO可以利用磁盘预读,一次读取一大片的数据,而随机IO每次都会定位到不同的数据页,效率大大降低。

三、如何避免回表?

  1. 避免使用select * ,如果返回的列正好是索引的列,尽量写出列名,从而避免回表查询。
  2. 用覆盖索引,联合索引的列包含所有返回的列
  3. 索引下推

四、什么时候MySQL会放弃索引直接回表查询?

  1. 如果回表次数太多,可能会放弃索引而使用全表扫描
  2. 如果返回的数据量超过了表的15%-30%,优化器可能会放弃二级索引,因为会回表产生太多随机IO不如直接全表扫描

五、一个查询走了索引但还是慢的原因是什么?

  1. 大概率是回表次数太多,产生大量随机IO。
  2. 利用explain 查看row 如果很高,代表回表代价高
  3. 优化办法就是使用覆盖索引,或者缩小结果集。

六、怎么判断一个查询到底有没有走索引?

  1. 使用explain,看extra列,using index表示使用了覆盖索引,没有回表查询,如果using index condition说明用到了索引下推,有回表。
  2. type 是index 全索引扫描,也有可能回表。

七、主键查询要回表吗?

  1. 回表查询只发生在二级索引中
  2. 主键查询是聚簇索引,叶子节点存的就是正行数据,所以不需要回表。
相关推荐
DBA小马哥2 小时前
文档型数据库MongoDB迁移替换至金仓数据库上线流程周期全解析
数据库·mongodb·文档型数据库
冰暮流星2 小时前
sql语言之where语句
java·数据库·sql
橘子132 小时前
MySQL基础(一)
数据库·mysql·php
難釋懷2 小时前
安装Redis
数据库·redis·缓存
jiayong232 小时前
Word协作与审阅实用手册
服务器·数据库·word
涵涵(互关)2 小时前
添加了 @TableId(type = IdType.AUTO) 但仍生成超大 ID
数据库·spring·mybatis
什么都不会的Tristan2 小时前
redis-原理篇-SDS
数据库·redis·缓存
陈天伟教授3 小时前
关系数据库-04. 关系的完整性-参照完整性
数据库·达梦数据库
刘大猫.3 小时前
mysql的cpu使用率100%问题排查
mysql·数据库cpu·mysql cpu占满·数据库服务cpu·数据库服务cpu占满·mysql cpu·数据库cpu占满