MySQL 5.6新特性MRR

一、什么是MRR 
MMR全称是Multi-Range Read,是MYSQL5.6优化器的一个新特性,在MariaDB5.5也有这个特性。优化的功能在使用二级索引做范围扫描的过程中减少磁盘随机IO和减少主键索引的访问次数。是优化器将随机 IO 转化为顺序 IO 以降低查询过程中 IO 开销的一种手段。(参考:https://blog.csdn.net/caomiao2006/article/details/52205177

二、MRR和没有MRR的区别 

给出一个简单的例子,在innodb表执行下面的查询:

SELECT non_key_column FROM tbl WHERE key_column=x

在没有MRR的情况下,它是这样得到结果的

1.  select key_column, pk_column from tb where key_column=x order  by key_column —>
假设这个结果集是t

2.  for each row in t ;
select non_key_column from tb where pk_column = pk_column_value。(回表)

在有MRR的情况下,它是这样执行的:
1.  select key_column, pk_column from tb where key_column = x  order by key_column —> 假设这个结果集是t
2.  将结果集t放在buffer里面(直到read_rnd_buffer_size这个buffer满了),然后对结果集t按照pk_column排序      —> 假设排序好的结果集是t_sort
3.  select non_key_column from tb where pk_column in (select pk_column from t_sort)

两者的区别主要是两点:

1. 没有MRR的情况下,随机IO增加,因为从二级索引里面得到的索引元组是有序,但是他们在主键索引里面却是无序的,所以每次去主键索引里面得到non_key_column的时候都是随机IO。(如果索引覆盖,那也就没必要利用MRR的特性了,直接从索引里面得到所有数据)

2. 没有MRR的情况下,访问主键索引的次数增加。没有MRR的情况下,二级索引里面得到多少行,那么就要去访问多少次主键索引(也不能完全这样说,因为mysql实现了BNL),而有了MRR的时候,次数就大约减少为之前次数t/buffer_size。

https://blog.csdn.net/liang_0609/article/details/44040357
https://dev.mysql.com/doc/refman/8.0/en/mrr-optimization.html
http://www.percona.com/blog/2012/03/21/multi-range-read-mrr-in-mysql-5-6-and-mariadb-5-5/

When MRR is used, the Extra column in EXPLAIN output shows Using MRR.

参考阅读:
MYSQL之ICP、MRR、BKA(推荐)