这几天看到mrr的东西,刚好看到以前我们组的一个小伙的博客,我看挺全的,就转过来了,原博客地址请戳

一 介绍
    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。
  2. select key_column, pk_column from tb where key_column=x order by key_column
  3. 第二步 通过第一步获取的主键来获取对应的值。
  4. for each pk_column value in rest do:
  5. select non_key_column from tb where pk_column=val


由于MySQL存储数据的方式: 辅助索引的存储顺序并非与主键的顺序一致,从图中可以看出,根据辅助索引获取的主键来访问表中的数据会导致随机的IO . 不同主键不在同一个page 里面时必然导致多次IO 和随机读。

在使用MRR优化特性的情况下,MySQL 针对基于辅助索引的查询策略是这样的:

  1. 第一步 先根据where条件中的辅助索引获取辅助索引与主键的集合,结果集为rest
  2. select key_column, pk_column from tb where key_column = x order by key_column
  3. 第二步 将结果集rest放在buffer里面(read_rnd_buffer_size 大小直到buffer满了),然后对结果集rest按照pk_column排序,得到结果集是rest_sort
  4. 第三步 利用已经排序过的结果集,访问表中的数据,此时是顺序IO.
  5. select non_key_column fromtb where pk_column in ( rest_sort )


从图示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;
  2. +----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+
  3. | id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                                     |
  4. +----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+
  5. | 1  | SIMPLE      | tbl   | range | key1          | key1 | 5       | NULL | 960  | Using index condition; Using MRR          |
  6. +----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+
  7. 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

六  参考文章 
《MariaDB Multi-Range Read Optimization》
 《MySQL Multi-Range Read Optimization》
 《Multi Range Read (MRR) in MySQL 5.6 and MariaDB 5.5》

最新文章

  1. [转]ubuntu linux下DNS重启后丢失
  2. [课程设计]Sprint One 总结&发表评论&团队贡献分
  3. java 多态奇怪现象,子类还没有构造完成就开始干活了,谁来帮我解释?
  4. php 数组排序 sort asort ksort
  5. DTCMS中部分IE8不支持webupload上传附件的控件,更改为ajaxfileupload
  6. 局域网yum服务器创建
  7. PHP Warning: phpinfo(): It is not safe to rely on the system's timezone setting
  8. java思考题
  9. 不完善的css怦然心动,有待改进...
  10. Asp .Net MVC4笔记之目录结构
  11. JAVAscript学习笔记 js事件 第一节 (原创) 参考js使用表
  12. 程序员的自我救赎---11.3:WinService服务
  13. Linux基础知识第二讲,文件目录命令使用
  14. Magento Meigee-Glam 主题的用法
  15. 浏览器LocalStroage使用
  16. POJ 2965&&1753
  17. Beand的高级特征
  18. centos6和7的防火墙开关
  19. EasyMock 常见异常
  20. spring in action 学习十一:property placeholder Xml方式实现避免注入外部属性硬代码化

热门文章

  1. 浅谈iOS中的userAgent
  2. 序列化,反序列化,模拟ATM机
  3. ado.net 连接,删除,添加
  4. js 数组排序
  5. 模拟实现ORM实例
  6. zju(2)vivi的配置编译和固化
  7. SpringBoot实例
  8. Python开发问题和解决方案汇集
  9. IOS第二天多线程-05NSOperationQueue 暂停,和恢复队列任务
  10. ThinkPHP 3.2.3 视图模型的使用