MySQL回表的性能消耗是多少

1 回表的性能消耗

无论单列索引 还是 联合索引,一个索引就对应一个独立的B+索引树,索引树节点仅包含:

  • 索引里的字段值

  • 主键值

MySQL回表的性能消耗:多少牺牲是必要的

即使根据索引树按条件找到所需数据,也仅是索引里的几个字段的值和主键值,万一你搞个select *,那就还得其他字段,就需回表,根据主键到聚簇索引里找,聚簇索引的叶节点是数据页,找到数据页才能把一行数据所有字段值读出来。所以类似

select * from table order by xx1,xx2,xx3

得从联合索引的索引树里按序取出所有数据,接着对每条数据都走一个主键的聚簇索引查找,性能不高。有时MySQL执行引擎可能认为,你要是类似

select * from table order by xx1,xx2,xx3

相当于得把联合索引和聚簇索引,两个索引的所有数据都扫描一遍,那还不如不走联合索引,直接全表扫描得了,这样就只需扫描一个主键索引。

但若形如:

select * from table order by xx1,xx2,xx3 limit 10

那执行引擎就知道你先扫描联合索引的索引树,拿到10条数据,接着对10条数据在聚簇索引里查找10次即可,那就还是会走联合索引。

2 覆盖索引

覆盖索引不是一种索引,只是一种基于索引查询的方式,即针对类似

select xx1,xx2,xx3 from table order by xx1,xx2,xx3

仅需联合索引里的几个字段的值,那就只需扫描联合索引的索引树,无需回表找其它字段,这种查询方式就是覆盖索引。所以当你使用联合索引时,注意是否可能会导致大量回表到聚簇索引,若回表聚簇索引的次数太多,可能就直接给你做成全表扫描而不走联合索引了。尽可能还是在SQL里指定你仅需要的字段,而不要暴力select *,最好直接走覆盖索引。即使无可避免地要回表,你也尽可能用limit、 where限定一下回表的次数,就从联合索引里筛选少数数据,再回表,这样性能好一点。



MySQL是目前全球广泛应用的开源关系型数据库管理系统,但是在使用MySQL时我们可能会遇到一个性能消耗问题——回表。回表是指在进行联接查询时需要从另一张表中获取数据,这一过程将消耗不少的性能资源。那么,为了保证查询效率,我们需要付出多少牺牲呢?
回表数据性能消耗
回表操作是针对联接查询中的非聚集列而言的,非聚集列通常指B-tree上的索引列。回表会对MySQL 的性能产生较大的影响,具体表现为以下几点:
1.频繁I/O操作:回表需要借助磁盘I/O进行数据读取,会增加时间复杂度和系统的磁盘负载。
2.降低内存效率:对于每个查询的回表操作,MySQL都会在内存中缓存一份数据,如果回表操作繁琐,那么内存的负荷也会大大增加。
3.对MySQL性能造成巨大影响:在大数据量的查询中,回表操作将导致MySQL的性能急剧下降,这是MySQL的巨大性能瓶颈之一。
回表的优化
如何优化MySQL回表操作呢?以下提供几个有效的方法:
1.合理设计索引:在数据库设计中,需要根据实际需求合理规划索引,避免一些不必要的的联表操作,从而减少回表的发生。
2.使用联合查询:联合查询可将多个表的数据在内存中进行计算,从而避免多次回表操作。
3.优化查询语句:对于查询中的冗余数据,应避免引入,优化查询语句,减少回表操作的发生。
为了使MySQL数据库系统能够拥有更快速、更生动的查询性能,我们应该积极采取优化措施,以达到最佳查询效率。
结论
MySQL回表操作繁琐将会对系统性能产生巨大的影响,从而影响数据查询效率。通过合理设计索引,使用联合查询和优化查询语句等方法,可以大大减少回表的发生。MySQL数据库的优化不是一蹴而就、一成不变的过程,而是一种持续攻克、不断完善的过程。只有不断优化、不断钻研,才能为数据库系统的完善发挥积极的作用。