在线精品99_中国九九盗摄偷拍偷看_91免费版在线观看_91.app_91高清视频在线_99热最新网站

MySQL 中MRR的作用是什么

134次阅读
没有评论

共计 3042 个字符,预计需要花费 8 分钟才能阅读完成。

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 的作用是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注丸趣 TV 行业资讯频道,感谢各位的阅读!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-01发表,共计3042字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)
主站蜘蛛池模板: 国产成人18黄网站免费网站 | 国产精品伦理 | 精品哟哟哟国产在线不卡 | 丰满熟女高潮毛茸茸欧洲 | 成人福利视频网址 | 色久在线 | 国产精品成人一区二区1 | 精品久久久久久人妻无码中文字幕 | 亚洲欧美日韩不卡一区二区三区 | 欧美一级香蕉毛片 | 国产性生交xxxxx无码 | 午夜亚洲| 99免费在线视频 | 爱做久久久久久 | 天堂最新版www在线观看 | 久久性综合亚洲精品电影网 | 99久久免费精品国产免费高清 | 成年女人色毛片免费看 | 免费女人18毛片a级毛片视频 | 亚洲av无码一区二区乱孑伦as | 久草不卡视频 | 亚洲伊人情人综合网站 | 久久99精品国产麻豆 | 亚洲无限观看 | 大尺度无遮挡激烈床震网站 | 成年免费a级毛片免费看 | 欧美中出在线 | 久久99爱re热视 | 亚洲精品自产拍在线观看动漫 | 岛国片人妻三上悠亚 | 国产成人精品视频播放 | 日韩免费 | 亚洲色大成网站www永久麻豆 | 欧美日韩成人在线 | 真人二十三式性视频(动) | 日韩久久综合 | 在线免费观看一区二区三区 | 国产特级毛片aaaaaa毛片 | 67pao国产成视频永久免费 | 亚洲v无码一区二区三区四区观看 | 国产精品福利一区二区久久 |