一 介绍 MySQL 5.6版本提供了很多性能优化的特性,其中之一就是 Multi-Range Read 多范围读(MRR) , 它的作用针对基于辅助/第二索引的查询,减少随机IO,并且将随机IO转化为顺序IO,提高查询效率。 二 原理 在没有MRR之前,或者没有开启MRR特性时,MySQL 针对基于辅助索引的查询策略是这样的: select non_key_column from tb wherekey_column=x; MySQL 执行查询的伪代码 第一步 先根据where条件中的辅助索引获取辅助索引与主键的集合,结果集为rest。 select key_column, pk_column from tb where key_column=x order by key_column 第二步 通过第一步获取的主键来获取对应的值。 for each pk_column value in rest do: select non_key_column from tb where pk_column=val
在使用MRR优化特性的情况下,MySQL 针对基于辅助索引的查询策略是这样的: 第一步 先根据where条件中的辅助索引获取辅助索引与主键的集合,结果集为rest select key_column, pk_column from tb where key_column = x order by key_column 第二步 将结果集rest放在buffer里面(read_rnd_buffer_size 大小直到buffer满了),然后对结果集rest按照pk_column排序,得到结果集是rest_sort 第三步 利用已经排序过的结果集,访问表中的数据,此时是顺序IO. select non_key_column fromtb where pk_column in ( rest_sort )
MySQL > explain select * from tbl where tbl.key1 between 1000 and 2000; +----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+ | 1 | SIMPLE | tbl | range | key1 | key1 | 5 | NULL | 960 | Using index condition; Using MRR | +----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+ 1 row in set (0.03 sec) 五 MRR的使用限 MRR 适用于以下两种情况。 1 range access 2 ref and eq_ref access, when they are using Batched Key Access.