MySQL 查询优化之 Multi-Range Read
MySQL 查询优化之 Multi-Range Read
在存储引擎中未缓存的大表,使用辅助索引的range scan检索数据, 可能会导致基表进行许多随机磁盘访问。
通过磁盘扫描多范围读取(MRR)优化,可以减少随机I/O,并且将随机I/O转化为顺序I/O,提高查询效率
MRR的工作原理
根据辅助索引的叶子结点上找到的主键值得集合存储到read_rnd_buffer
中,然后在该buffer中对主键值进行排序,最后再利用已经排序好的主键值的集合,去访问表中的数据,这样就由原来的随机/O变成了顺序I/O
,降低了查询过程中的I/O消耗
。
SELECT * FROM t WHERE key_part1>=1000 and key_part1<2000 AND key_part2=1000;
表t
有(key_part1,key_part2
)的联合索引因此索引根据key_part1,key_part2
的位置关系进行排序。
若没有MRR,此时查询类型为Range。SQL优化器会先将key_part1>1000 and key_part2<2000的数据线取出来,即使key_part2不等于1000。待取出的行数据后在根据key_part2的条件进行过滤,这会导致无用的数据被取出,如果有大量的数据且其key_part2不等于1000,则启用MRR优化会使性能有巨大的提升
启用MRR优化,优化器会先将查询条件进行拆分,然后在进行数据查询。上述语句,优化器会将查询条件拆分为(1000,1000),(1001,1000),(1002,1000),...,(1999,1000),然后在根据这些拆分出的条件进行数据查询
MRR开启与关闭
通过参数 optimizer_switch
的标记来控制是否使用MRR
当设置
mrr=on
时,表示启用MRR优化。mrr_cost_based
表示是否通过cost base
基于成本的方式来启用MRR如果选择mrr=on,mrr_cost_based=off,则表示总是开启MRR优化,参数read_rnd_buffer_size 用来控制键值缓冲区的大小。
默认情况下:
mrr=on,mrr_cost_based=on
使用MRR示例
使用MRR时,EXPLAIN输出中的Extra
列显示Using MRR
。
mysql> show index from salaries;
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| salaries | 0 | PRIMARY | 1 | emp_no | A | 300557 | NULL | NULL | | BTREE | | |
| salaries | 0 | PRIMARY | 2 | from_date | A | 2838426 | NULL | NULL | | BTREE | | |
| salaries | 1 | emp_no | 1 | emp_no | A | 299974 | NULL | NULL | | BTREE | | |
| salaries | 1 | idx_salary | 1 | salary | A | 73229 | NULL | NULL | | BTREE | | |
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec) 默认使用的是mrr=on,mrr_cost_based=on mysql> explain select * from salaries s where s.salary between 68000 and 70000;
+----+-------------+-------+------------+-------+---------------+------------+---------+------+--------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+--------+----------+-----------------------+
| 1 | SIMPLE | s | NULL | range | idx_salary | idx_salary | 4 | NULL | 222726 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+--------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec) 设置总是开启mrr mysql> set optimizer_switch='mrr=on,mrr_cost_based=off';
Query OK, 0 rows affected (0.00 sec) mysql> explain select * from salaries s where s.salary between 68000 and 70000;
+----+-------------+-------+------------+-------+---------------+------------+---------+------+--------+----------+----------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+--------+----------+----------------------------------+
| 1 | SIMPLE | s | NULL | range | idx_salary | idx_salary | 4 | NULL | 222726 | 100.00 | Using index condition; Using MRR |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+--------+----------+----------------------------------+
1 row in set, 1 warning (0.00 sec)
参考文档
https://dev.mysql.com/doc/refman/5.7/en/mrr-optimization.html
https://www.cnblogs.com/vadim/p/7403544.html
MySQL 查询优化之 Multi-Range Read的更多相关文章
- Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析 Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析1 存 ...
- MySQL查询优化之explain的深入解析
在分析查询性能时,考虑EXPLAIN关键字同样很管用.EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作.以及MySQL成功返回结果集需要执行的行数.expla ...
- Mysql查询优化器
Mysql查询优化器 本文的目的主要是通过告诉大家,查询优化器为我们做了那些工作,我们怎么做,才能使查询优化器对我们的sql进行优化,以及启示我们sql语句怎么写,才能更有效率.那么到底mysql到底 ...
- MySQL查询优化之explain
在分析查询性能时,考虑EXPLAIN关键字同样很管用.EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作.以及MySQL成功返回结果集需要执行的行数.expla ...
- Mysql查询优化器浅析
--Mysql查询优化器浅析 -----------------------------2014/06/11 1 定义 Mysql查询优化器的工作是为查询语句选择合适的执行路径.查询优化器的代码 ...
- MySQL查询优化之explain详解
MySQL explain命令显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: ...
- (转)支持Multi Range Read索引优化
支持Multi Range Read索引优化 原文:http://book.51cto.com/art/201701/529465.htm http://book.51cto.com/art/2016 ...
- MySQL 查询优化之 Block Nested-Loop 与 Batched Key Access Joins
MySQL 查询优化之 Block Nested-Loop 与 Batched Key Access Joins 在MySQL中,可以使用批量密钥访问(BKA)连接算法,该算法使用对连接表的索引访问和 ...
- MySQL 查询优化之 Index Condition Pushdown
MySQL 查询优化之 Index Condition Pushdown Index Condition Pushdown限制条件 Index Condition Pushdown工作原理 ICP的开 ...
随机推荐
- C - Brackets
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> ...
- Windows类标识符及其妙用
Windows类标识符 百度百科这样解释: Windows的类标识符class identifier也称为CLASSID或CLSID,是与某一个类对象相联系的唯一标记(UUID).一个准备创建多个对象 ...
- JTextArea设置滚动条
应将JTextArea置于JScrollPanel中 若要使只有垂直滚动条而没有水平滚动条,使用JTextArea.setLineWrap(true),自动换行. 以下摘自[url]http:// ...
- spring boot使用AbstractXlsView导出excel
一.maven依赖jar包 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi ...
- 最大流bfs
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #i ...
- (C#)asp_net调试错误解决方法收集(1)
(C#)asp_net调试错误解决方法收集(1) 2007-11-2309:20 一.异常详细信息:System.InvalidOperationException:对于不返回任何键列信息的Selec ...
- dataTable 中数据的居中显示
遇到了一个小问题,就是在向dataTable中添加数据时,数据总是向左对齐,而dataTable又没有设置数据对齐的方法,这里写一个在网上看到的一个方法,分享出来看一下,简单实用. html代码如图1 ...
- Java开发中存在这样的代码,反而影响整体整洁和可读性
不完美的库类 不完美的库类(Incomplete Library Class) 当一个类库已经不能满足实际需要时,你就不得不改变这个库(如果这个库是只读的,那就没辙了). 问题原因 许多编程技术都建立 ...
- JVM垃圾回收机制三
垃圾回收器 分代垃圾回收常见的垃圾回收器 判断一个垃圾回收器好坏的标准 1.吞吐量越高越好 2.工作线程暂停时间越短越好. Serial垃圾回收器 串行回收器时最古老的最基本的垃圾回收器,工作线程会产 ...
- jQuery Deferred对象详细源码分析(-)
本系列文章讲介绍这个Deferred东西到底拿来干什么,从1.5版本加进来,jQuery的很多代码都重写了.直接先上源码分析了,清楚了源码分析,下节将讲具体的应用 以及应用场景. 创建对象 var d ...