一 介绍
    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 (.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》

MySQL5.6新特性之Multi-Range Read的更多相关文章

  1. [MySQL5.6 新特性] 全局事务标示符(GTID)

    GTID的全称为 global transaction identifier  , 可以翻译为全局事务标示符,GTID在原始master上的事务提交时被创建.GTID需要在全局的主-备拓扑结构中保持唯 ...

  2. MySQL5.6 新特性之GTID【转】

    转自 MySQL5.6 新特性之GTID - jyzhou - 博客园http://www.cnblogs.com/zhoujinyi/p/4717951.html 背景: MySQL5.6在5.5的 ...

  3. [转]MySQL5.6新特性之Multi-Range Read

    这几天看到mrr的东西,刚好看到以前我们组的一个小伙的博客,我看挺全的,就转过来了,原博客地址请戳 一 介绍    MySQL 5.6版本提供了很多性能优化的特性,其中之一就是 Multi-Range ...

  4. MySQL5.6新特性Index conditontion pushdow

    index condition pushdown是MySQL5.6的新特性,主要是对MySQL索引使用的优化. Index condition push简称ICP,索引条件下推,将索引条件从serve ...

  5. mysql5.7新特性探究

    一.MySql5.7增加的特性 1.MySql服务方面新特性 1) 初始化方式改变 MySql5.7之前版本初始化方式: scripts/mysql_install_db MySql5.7版本初始化方 ...

  6. MySQL5.7新特性

    MySQL5.7介绍 身处 MySQL 这个圈子,能够切身地感受到大家对 MySQL 5.7 的期待和热情,似乎每个人都迫不及待的想要了解.学习和使用 MySQL 5.7.那么,我们不禁要问, MyS ...

  7. 使用mysql5.7新特性(虚拟列)解决使用前通配符性能问题

    众所周知,在mysql里的后通配符可以使用索引查找,前通配查询却无法使用到索引,即使是使用到了索引,也是使用了索引全扫描,效率依然不高,再MySQL5.7之前,一直都没有好的办法解决,但是到了MySQ ...

  8. 使用mysql5.7新特性解决前通配符查询性能问题

    众所周知,在mysql里的后通配符可以使用索引查找,前通配查询却无法使用到索引,即使是使用到了索引,也是使用了索引全扫描,效率依然不高,再MySQL5.7之前,一直都没有好的办法解决,但是到了MySQ ...

  9. MySQL5.6 新特性之GTID

    背景: MySQL5.6在5.5的基础上增加了一些改进,本文章先对其中一个一个比较大的改进"GTID"进行说明. 概念: GTID即全局事务ID(global transactio ...

随机推荐

  1. git 继续前进篇

    * git 输入 git log (--all)命令后出现<END>标记? 按q退出历史记录列表即可 * 继续前一天的  继续推送到github  步骤看图 先 链接到 之前工作区 的 文 ...

  2. python基础初识介绍以及安装

    python介绍 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承. ...

  3. LibHaru编译使用

    最近公司准备在PDF方面发力了,我也要行动起来,就找到了LibHaru这个开源库 编译Libharu需要用到zlib库和libpng库,libpng库又依赖zlib库. zlib 下载地址:http: ...

  4. MySQL:数据表基本操作

    数据表基本操作 注意点: 1.数据表中已经有数据时,轻易修改数据类型,有可能因为不同的数据类型的数据在机器 中存储的方式及长度并不相同,修改数据类型可能会影响到数据表中已有的数据类型. 2.  数据表 ...

  5. 基于ArduinoLeonardo板子的BadUSB攻击实战

    0X00 前言 在Freebuf上许多同学已经对HID攻击谈了自己的看法,如维克斯同学的<利用Arduino快速制作Teensy BadUSB>无论从科普还是实践都给我们详尽的描述了Bad ...

  6. 后台返回json字符串 页面js报错 Uncaught SyntaxError: Unexpected identifier

    后台json字符串是 [{"name": "报销申请", "id": "start"}, {"name&quo ...

  7. idea 中新建Servlet

    本文转载自 :itellij idea创建javaWeb以及Servlet简单实现  一.创建并设置javaweb工程 1.创建javaweb工程File --> New --> Proj ...

  8. 【算法基础】卡尔曼滤波KF

    kalman filter KCF 尺度变化是跟踪中比较基本和常见的问题,前面介绍的三个算法都没有尺度更新,如果目标缩小,滤波器就会学习到大量背景信息,如果目标扩大,滤波器就跟着目标局部纹理走了,这两 ...

  9. ldd 查看程序依赖库

    ldd 查看程序依赖库 https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/ldd.html

  10. [LeetCode&Python] Problem 888. Fair Candy Swap

    Alice and Bob have candy bars of different sizes: A[i] is the size of the i-th bar of candy that Ali ...