千家信息网

MySQL 中MRR的作用是什么

发表于:2025-02-13 作者:千家信息网编辑
千家信息网最后更新 2025年02月13日,MySQL 中MRR的作用是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。执行一个范围查询:mysql > explain sele
千家信息网最后更新 2025年02月13日MySQL 中MRR的作用是什么

MySQL 中MRR的作用是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

执行一个范围查询:

mysql > explain select * from stu where age between 10 and 20; +----+-------------+-------+-------+------+---------+------+------+-----------------------+ | id | select_type | table | type  | key  | key_len | ref  | rows | Extra                 | +----+-------------+-------+-------+----------------+------+------+-----------------------+ |  1 | SIMPLE      |  stu  | range | age  | 5       | NULL |  960 | Using index condition | +----+-------------+-------+-------+----------------+------+------+-------------

当这个 sql 被执行时,MySQL 会按照下图的方式,去磁盘读取数据(假设数据不在数据缓冲池里):

图中红色线就是整个的查询过程,蓝色线则是磁盘的运动路线。

这张图是按照 Myisam 的索引结构画的,不过对于 Innodb 也同样适用。

对于 Myisam,左边就是字段 age 的二级索引,右边是存储完整行数据的地方。

先到左边的二级索引找,找到第一条符合条件的记录(实际上每个节点是一个页,一个页可以有很多条记录,这里我们假设每个页只有一条),接着到右边去读取这条数据的完整记录。

读取完后,回到左边,继续找下一条符合条件的记录,找到后,再到右边读取,这时发现这条数据跟上一条数据,在物理存储位置上,离的贼远!

咋办,没办法,只能让磁盘和磁头一起做机械运动,去给你读取这条数据。

第三条、第四条,都是一样,每次读取数据,磁盘和磁头都得跑好远一段路。

磁盘的简化结构可以看成这样:

可以想象一下,为了执行你这条 sql 语句,磁盘要不停的旋转,磁头要不停的移动,这些机械运动,都是很费时的。

10,000 RPM(Revolutions Per Minute,即转每分) 的机械硬盘,每秒大概可以执行 167 次磁盘读取,所以在极端情况下,MySQL 每秒只能给你返回 167 条数据,这还不算上 CPU 排队时间。

上面讲的都是机械硬盘,SSD 的土豪,请随意 - -

对于 Innodb,也是一样的。 Innodb 是聚簇索引(cluster index),所以只需要把右边也换成一颗叶子节点带有完整数据的 B+ tree 就可以了。

顺序读:一场狂风暴雨般的革命

到这里你知道了磁盘随机访问是多么奢侈的事了,所以,很明显,要把随机访问转化成顺序访问:

mysql > set optimizer_switch='mrr=on'; Query OK, 0 rows affected (0.06 sec)  mysql > explain select * from stu where age between 10 and 20; +----+-------------+-------+-------+------+---------+------+------+----------------+ | id | select_type | table | type  | key  | key_len | ref  | rows | Extra          | +----+-------------+-------+-------+------+---------+------+------+----------------+ |  1 | SIMPLE      | tbl   | range | age  |    5    | NULL |  960 | ...; Using MRR | +----+-------------+-------+-------+------+---------+------+------+----------------+

我们开启了 MRR,重新执行 sql 语句,发现 Extra 里多了一个「Using MRR」。

这下 MySQL 的查询过程会变成这样:

对于 Myisam,在去磁盘获取完整数据之前,会先按照 rowid 排好序,再去顺序的读取磁盘。

对于 Innodb,则会按照聚簇索引键值排好序,再顺序的读取聚簇索引。

顺序读带来了几个好处:

1、磁盘和磁头不再需要来回做机械运动;

2、可以充分利用磁盘预读

比如在客户端请求一页的数据时,可以把后面几页的数据也一起返回,放到数据缓冲池中,这样如果下次刚好需要下一页的数据,就不再需要到磁盘读取。这样做的理论依据是计算机科学中著名的局部性原理:

当一个数据被用到时,其附近的数据也通常会马上被使用。

3、在一次查询中,每一页的数据只会从磁盘读取一次

MySQL 从磁盘读取页的数据后,会把数据放到数据缓冲池,下次如果还用到这个页,就不需要去磁盘读取,直接从内存读。

但是如果不排序,可能你在读取了第 1 页的数据后,会去读取第2、3、4页数据,接着你又要去读取第 1 页的数据,这时你发现第 1 页的数据,已经从缓存中被剔除了,于是又得再去磁盘读取第 1 页的数据。

而转化为顺序读后,你会连续的使用第 1 页的数据,这时候按照 MySQL 的缓存剔除机制,这一页的缓存是不会失效的,直到你利用完这一页的数据,由于是顺序读,在这次查询的余下过程中,你确信不会再用到这一页的数据,可以和这一页数据说告辞了。

顺序读就是通过这三个方面,最大的优化了索引的读取。

别忘了,索引本身就是为了减少磁盘 IO,加快查询,而 MRR,则是把索引减少磁盘 IO 的作用,进一步放大。

一些关于这场革命的配置

和 MRR 相关的配置有两个:

  • mrr: on/off

  • mrr_cost_based: on/off

第一个就是上面演示时用到的,用来打开 MRR 的开关:

mysql > set optimizer_switch='mrr=on';

如果你不打开,是一定不会用到 MRR 的。

另一个,则是用来告诉优化器,要不要基于使用 MRR 的成本,考虑使用 MRR 是否值得(cost-based choice),来决定具体的 sql 语句里要不要使用 MRR。

很明显,对于只返回一行数据的查询,是没有必要 MRR 的,而如果你把 mrr_cost_based 设为 off,那优化器就会通通使用 MRR,这在有些情况下是很 stupid 的,所以建议这个配置还是设为 on,毕竟优化器在绝大多数情况下都是正确的。

另外还有一个配置 read_rnd_buffer_size ,是用来设置用于给 rowid 排序的内存的大小。

显然,MRR 在本质上是一种用空间换时间的算法。MySQL 不可能给你无限的内存来进行排序,如果 read_rnd_buffer 满了,就会先把满了的 rowid 排好序去磁盘读取,接着清空,然后再往里面继续放 rowid,直到 read_rnd_buffer 又达到 read_rnd_buffe 配置的上限,如此循环。

看完上述内容,你们掌握MySQL 中MRR的作用是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

数据 磁盘 索引 顺序 查询 就是 机械 配置 右边 磁头 要不 运动 作用 机械运动 内存 情况 缓存 语句 过程 排序 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 我的世界网易下界更新服务器 网站服务器的根目录 小学网络安全文明教育图片 浙江正泰网络技术有限公司保安 infuse无法连接服务器 惠州定制冷库软件开发 电信服务器管理设置 英国网络安全治理论文 未来会诞生哪些软件开发项目 电脑斜杠怎么打网络安全密钥 机房网络安全风险 图片怎么打印到服务器上 数据库按存储内容分类 校园网络安全监控软件 网络安全防护有哪几种类型 郑州互联网软件开发收费报价表 esxi服务器上传文件 你的网络无法连接到服务器 复垣互联网科技有限公司 中国网络安全事件报告 网络技术管理办法 上海科锦信息网络技术 南京伟全网络技术有限公司 数据库中的界面 java批量导出数据库 k2p dns服务器未响应 平罗县网络安全和信息化服务中心 网络安全投融资月报 安全服务器异常怎么办啊 没有买国泰安数据库能发文章
0