当一个数据被用到时,其附近的数据也通常会马上被使用 。
3、在一次查询中,每一页的数据只会从磁盘读取一次MySQL 从磁盘读取页的数据后,会把数据放到数据缓冲池,下次如果还用到这个页,就不需要去磁盘读取,直接从内存读 。
但是如果不排序,可能你在读取了第 1 页的数据后,会去读取第2、3、4页数据,接着你又要去读取第 1 页的数据,这时你发现第 1 页的数据,已经从缓存中被剔除了,于是又得再去磁盘读取第 1 页的数据 。
而转化为顺序读后,你会连续的使用第 1 页的数据,这时候按照 MySQL 的缓存剔除机制,这一页的缓存是不会失效的,直到你利用完这一页的数据,由于是顺序读,在这次查询的余下过程中,你确信不会再用到这一页的数据,可以和这一页数据说告辞了 。
顺序读就是通过这三个方面,最大的优化了索引的读取 。别忘了,索引本身就是为了减少磁盘 IO,加快查询,而 MRR,则是把索引减少磁盘 IO 的作用,进一步放大 。尾声和 MRR 相关的配置 有两个:
- mrr: onoff
- mrr_cost_based: onoff
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 配置的上限,如此循环 。
推荐阅读
- 语言之间的哲学C#和Java之间主要区别
- MySQL架构之MHA架构实战
- Java程序员最常犯的错TOP10,你还在犯么?
- MySQL中的行级锁,表级锁,页级锁
- 皖西黄大茶多少钱斤,六安有什么好玩的
- 不适宜喝黄茶的人,黄茶适合什么人喝
- 黄小茶购买技巧,有效的饮茶技巧
- 海马宫茶的价格是多少,海马宫茶的价值功能
- 安徽的黄茶有哪些,黄茶有哪些
- 黄茶有什么功效,黄茶的功效有哪些