尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MySQL回表机制解析与优化策略

MySQL回表机制解析与优化策略 一MySQL中的回表是什么意思利用二级索引进行查询除索引列值和主键以外的值时由于二级索引的叶子节点中存储的只有索引所对应列的值和主键id这样就导致我们查询不到所以Innodb就会重新使用查到的主键id回到表中找到对应的行数据因为主键索引的叶子节点存储的是对应行的全部数据所以可以找到举个例子这里使用select * from user where age 20;来进行举例说明user表上有三个字段分别是id,name,age这里age上有索引1首先走age的二级索引找到age 20 的记录拿到主键值2由于我们使用了select * 导致我们还需要name字段但是age索引中并没有name这时我们要用找到的主键id重新回到表中找到全部对应行数据字段id,name,age二回表所带来的性能代价回表并不是重新查询一遍表那么简单因为查询二级索引所查询到的主键id并不是连续的就比如age 20 的用户有很多所以查询到的id是无序的可能的顺序102393213421390使用这些id去主键索引中查会导致定位到不同的数据页从而产生大量的随机IO顺序IO读写的数据在磁盘上是一个挨着一个的读取一大块相邻磁盘页磁头也会很快的进行移动不会出现较大幅度的移动随机IO读写的数据分布在磁盘上的随机位置如果数据一多那么效率将会有很明显的下降三如何避免/减少回表1.覆盖索引如果我们想避免回表那么我们就要让所查询字段出现在二级索引中就比如我建立索引为idx_name_age(name,age),那么select name from user where age 20就不会进行回表索引的叶子节点就存储了id,name,age直接返回就ok了2.索引下推这个功能是在MySQL5.6之后才出现的索引下推index condition pushdownICP将一些where条件下推到引擎层先进行过滤再对过滤后的条件进行回表没有通过的条件直接就不回表了这样可以大大减少回表的次数举个例子现在依旧一个索引idx_name_age(name,age)where name 张% and age 20,如果没有ICP那么先查询到姓张的人的id然后对这些人全部进行回表回表后拿到的数据再进行age20过滤如果开启索引下推那就会先找到name 张%的范围然后再在索引叶子节点中找到过滤age20这样就少回表不符合条件的了3.减少select *的使用使用这个select *基本上肯定要回表所以就不要图方便随便使用这个select *四如何判断查询有没有回表看Explain中的Extra值如果是Using Index那么是覆盖索引没有回表如果是Using Index Conditiion那么就是发生了ICP回表了如果type值为Index表示全索引扫描不一定发生了回表五主键查询需要回表吗不需要回表主键索引的叶子节点中就包含整列数据直接就可以查到不需要回表
返回列表