一 介绍
MySQL 5.6版本提供了很多性能优化的特性,其中之一就是 Multi-Range Read 多范围读(MRR) , 它的作用针对基于辅助/第二索引的查询,减少随机IO,并且将随机IO转化为顺序IO,提高查询效率。
二 原理
在没有MRR之前,或者没有开启MRR特性时,MySQL 针对基于辅助索引的查询策略是这样的:
1 | select non_key_column from tb wherekey_column=x; |
MySQL 执行查询的伪代码
1 | 第一步 先根据where条件中的辅助索引获取辅助索引与主键的集合,结果集为rest。 |
由于MySQL存储数据的方式: 辅助索引的存储顺序并非与主键的顺序一致,从图中可以看出,根据辅助索引获取的主键来访问表中的数据会导致随机的IO . 不同主键不在同一个page 里面时必然导致多次IO 和随机读。
在使用MRR优化特性的情况下,MySQL 针对基于辅助索引的查询策略是这样的:
1 | 第一步 先根据where条件中的辅助索引获取辅助索引与主键的集合,结果集为rest |
从图示MRR原理,MySQL 将根据辅助索引获取的结果集根据主键进行排序,将乱序化为有序,可以用主键顺序访问基表,将随机读转化为顺序读,多页数据记录可一次性读入或根据此次的主键范围分次读入,以减少IO操作,提高查询效率。
三 相关参数
我们可以通过参数 optimizer_switch 的标记来控制是否使用MRR,当设置mrr=on时,表示启用MRR优化。mrr_cost_based 表示是否通过 cost base 的方式来启用MRR。如果选择mrr=on,mrr_cost_based=off,则表示总是开启MRR优化。
参数 read_rnd_buffer_size 用来控制键值缓冲区的大小。
四 案例介绍
当开启MRR时
1 | MySQL > explain select * from tbl where tbl.key1 between 1000 and 2000; |
五 MRR的使用限制
MRR 适用于以下两种情况。
- 1 range access
- 2 ref and eq_ref access, when they are using Batched Key Access
六 参考文章
《MariaDB Multi-Range Read Optimization》
《MySQL Multi-Range Read Optimization》
《Multi Range Read (MRR) in MySQL 5.6 and MariaDB 5.5》
本文地址:http://xnerv.wang/mysql56-new-feature-multi-range-read/
转载自:【MySQL】MySQL5.6新特性之Multi-Range Read