MRR针对于辅助索引上的范围查询进行优化,收集辅助索引对应主键rowid。进行排序后回表查询,随机IO转顺序IO

当我们需要对大表(基于辅助索引)进行范围扫描时,会导致产生许多随机/O。而对于普通磁盘来说,随机的性能很差,会遇到瓶颈,在 MySQL 5.6/5.7和MariaDB5.3/5.5/10.0/10.1版本里对这种情况进行了优化,一个新的名词 Multi Range Read(MRR)出现了,优化器会先扫描辅助索引,然后收集每行的主键(rowid ),并对主键进行排序(排序结果存储到read_rnd_buffer),此时就可以用主键顺序访问基表,即用顺序IO代替随机IO。

而MRR的优化在于,并不是每次通过辅助索引读取到数据就回表去取记录,范围扫描(range access)中MySQL将扫描到的数据存入由 read_rnd_buffer_size 变量定义的内存大小中,默认256K。然后对其按照Primary Key(RowID)排序,然后使用排序好的数据进行顺序回表,因为我们知道InnoDB中叶子节点数据是按照PRIMARY KEY(ROWID)进行顺序排列的,所以我们可以认为,如果按照主键的递增顺序查询的话,对磁盘的读比较接近顺序读,能够提升读性能。这对于IO-bound类型的SQL查询语句带来性能极大的提升。

MRR 能够提升性能的核心在于,这条查询语句在索引上做的是一个范围查询(也就是说,这是一个多值查询),可以得到足够多的主键id。这样通过排序以后,再去主键索引查数据,才能体现出“顺序性”的优势。所以MRR优化可用于range,ref,eq_ref类型的查询,工作方式如下图:

简单说:使用辅助索引进行范围查询时,MRR会收集并排序好符合范围查询条件的rowid。然后通过顺序的rowid去回表查询数据记录。 MRR 通过把「随机磁盘读」,转化为「顺序磁盘读」,从而提高了索引查询的性能。

mysql中mrr相关操作

mysql默认开启MRR优化。但是由优化器决定是否真正使用MRR(mrr=on,mrr_cost_based=on),因为有些时候优化器认为不使用MRR性能会更好!查询MRR的开启状态如下:

SHOW VARIABLES LIKE '%optimizer_switch%'

index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=off,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on

关闭MRR优化,不强制使用MRR

set optimizer_switch='mrr=off,mrr_cost_based=on';

k_1是sbtest1 表的一个辅助索引,执行计划如下:

EXPLAIN SELECT * from sbtest1 force index(k_1) where k BETWEEN 1000 and 55555

image.png

image.png

再来看开启MRR,并强制使用。可以看到执行计划的Extra列多了Using MRR

set optimizer_switch='mrr=on,mrr_cost_based=off';

image.png

image.png

mrr=on会开启MRR优化功能,mrr_cost_based 则是用来告诉优化器,要不要基于使用 MRR 的成本,考虑使用 MRR 是否值得(cost-based choice),来决定具体的 sql 语句里要不要使用 MRR。很明显,对于只返回一行数据的查询,是没有必要 MRR 的,而如果你把 mrr_cost_based 设为 off,那优化器就会通通使用 MRR。建议这个配置还是设为 on,毕竟优化器在绝大多数情况下都是正确的。另外还有一个配置 read_rnd_buffer_size ,是用来设置用于给 rowid 排序的内存的大小。显然,MRR 在本质上是一种用空间换时间的算法。MySQL 不可能给你无限的内存来进行排序,如果 read_rnd_buffer 满了,就会先把满了的 rowid 排好序去磁盘读取,接着清空,然后再往里面继续放 rowid,直到 read_rnd_buffer 又达到 read_rnd_buffe 配置的上限,如此循环。

另外 MySQL 的其中一个分支 Mariadb 对 MySQL 的 MRR 做了很多优化。

SHOW VARIABLES LIKE '%read_rnd_buffer%' -- 262144 字节 0.25M

注意:MRR 只是针对优化回表查询的速度,当不需要回表访问的时候,MRR就失去意义了(比如覆盖索引)

optimizer_switch可以是全局的,也可以是会话级的。当然,除了调整参数外,数据库也提供了语句级别的开启或关闭MRR,使用方法如下:

EXPLAIN SELECT /*+ MRR(sbtest1)*/ * from sbtest1 force index(k_1) where k BETWEEN 1000 and 55555

image.png

mysql optimizer mrr_mysql 索引优化特性之MRR相关推荐

  1. 读薄《高性能MySql》(三)索引优化

    读薄<高性能MySql>(一)MySql基本知识 读薄<高性能MySql>(二)Scheme与数据优化 读薄<高性能MySql>(三)索引优化 读薄<高性能M ...

  2. mysql存储引擎 索引优化_MySQL存储引擎,索引及基本优化策略

    存储引擎 与Oracle, SQL Server这些数据库不同,MySQL提供了多种存储引擎.什么是存储引擎?存储引擎其实就是一套对于数据如何存储,查询,更新,建立索引等接口的实现.不同存储引擎特性有 ...

  3. MySql数据结构、索引优化原则(Java劝退师)

    MySql(InnoDB)随手记 MySql索引为甚么选择的是B+.几种数据结构相比,二叉树.红黑树无法保证树的高度可控.当在内存中操作的时候,这些数据结构由于树深度造成的影响可能还能接受, 但作为数 ...

  4. MYSQL高级篇-----索引优化分析

    索引优化分析 下面是目录可跳转对应页面学习: 2. 索引优化分析 2.1 原因 SQL执行顺序 2.2 常见通用的join查询 2.3 索引 2.3.1 索引分类(重点) 2.3.2 索引结构 2.3 ...

  5. Mysql详解——索引优化

    本篇文章是对Mysql索引的创建以及优化进行一个介绍,关于索引的底层原理可以看我另一篇文章:Mysql详解--索引详解 文章目录 一.索引的创建和设计原则 1. 索引的声明和使用 1.1 索引的分类: ...

  6. MySQL如何利用索引优化ORDER BY排序语句

    MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度. MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作. 通 ...

  7. MySql ORDER BY 索引优化

    上一篇:MySql 索引优化 MySql 支持两种方式的排序,FileSort 和 Index ,Index 效率高,它指的是 MySql 扫描索引本身完成排序.FileSort 会对数据使用一个外部 ...

  8. mysql 更新索引_MySQL索引优化

    MySQL支持的索引类型 B-tree索引的特点 1.B-tree索引以B+树的结构存储数据 2.B-tree索引能够加快数据的查询速度 3.B-tree索引更适合进行行范围查找 B-tree结构图 ...

  9. MySQL高级:索引优化之防止索引失效

    前言:数据库索引优化,但是可能出现索引失效,我们该怎样防止这种情况发生呢>> 文章目录 1. 案例建表: 1.1 staffs表 1.2 建立索引: 2.案例:索引失效 2.1 全面匹配索 ...

最新文章

  1. mysql 建表,解决中文输入
  2. WebView跳转到底部
  3. java将030A转换为方块_JAVA试题
  4. 使用mysql导入数据
  5. matlab 辅助函数 —— 文件下载与文件解压
  6. [20180124]测试SQLNET.EXPIRE_TIME参数3
  7. Au入门系列之五:轨道与轨道控制​
  8. omnet++tictoc12案例解析
  9. DOCTYPE 的作用是什么
  10. 郊区春游(状压dp)
  11. 通往真理的最短路径 - 【复数】科普/详解
  12. 一文看懂区块链架构设计(附知识图谱)
  13. 处理打包后的.air文件不能打开的情况
  14. 商用密码产品认证实施细则智能密码钥匙
  15. threejs重置模型的相机位置和角度
  16. 非接触式红外额温计方案
  17. STM32MP157-Linux输入设备应用编程-多点触摸屏编程
  18. 程序猿九重天,你到第几重了
  19. 厨房(博客搬家,2007年写)
  20. 电赛校赛-三相逆变电源设计(模拟部分)

热门文章

  1. Chrome 的小恐龙游戏,被我破解了...
  2. spire在word的文档页眉加上图片
  3. 网络收音机java,如何用java实现网络收音机
  4. 中企动力与重庆悦之恋食品同行 领跑全网门户平台
  5. 电能质量监测和分析仪器的设计与应用
  6. 发力5G,AICS或将打造全新智联时代!
  7. 机器学习之决策树算法(3)
  8. win10恶意软件删除工具
  9. Access数据库是什么
  10. 风讯(FoosunCMS) SetNextOptions.asp注入漏洞利用