Reading rows using a range scan on a secondary index can result in many random disk accesses to the base table when the table is large and not stored in the storage engine's cache. 当基表较大且未存储在存储引擎的缓存中时,在次索引上使用范围扫描读取行可能会导致对基表的多次随机磁盘访问。With the Disk-Sweep Multi-Range Read (MRR) optimization, MySQL tries to reduce the number of random disk access for range scans by first scanning the index only and collecting the keys for the relevant rows. 通过磁盘扫描多范围读取(MRR)优化,MySQL试图通过首先只扫描索引并收集相关行的键来减少范围扫描的随机磁盘访问次数。Then the keys are sorted and finally the rows are retrieved from the base table using the order of the primary key. 然后对键进行排序,最后使用主键的顺序从基表中检索行。The motivation for Disk-sweep MRR is to reduce the number of random disk accesses and instead achieve a more sequential scan of the base table data.磁盘扫描MRR的动机是减少随机磁盘访问的次数,而是实现对基表数据的更连续的扫描。
The Multi-Range Read optimization provides these benefits:多范围读取优化提供了以下好处:
MRR enables data rows to be accessed sequentially rather than in random order, based on index tuples. MRR允许基于索引元组按顺序而不是按随机顺序访问数据行。The server obtains a set of index tuples that satisfy the query conditions, sorts them according to data row ID order, and uses the sorted tuples to retrieve data rows in order. 服务器获取一组满足查询条件的索引元组,根据数据行ID顺序对它们进行排序,并使用排序后的元组按顺序检索数据行。This makes data access more efficient and less expensive.这使得数据访问更高效,成本更低。
MRR enables batch processing of requests for key access for operations that require access to data rows through index tuples, such as range index scans and equi-joins that use an index for the join attribute. MRR支持对需要通过索引元组访问数据行的操作的密钥访问请求进行批处理,例如范围索引扫描和使用连接属性索引的等同连接。MRR iterates over a sequence of index ranges to obtain qualifying index tuples. MRR迭代一系列索引范围以获得合格的索引元组。As these results accumulate, they are used to access the corresponding data rows. It is not necessary to acquire all index tuples before starting to read data rows.<随着这些结果的累积,它们将用于访问相应的数据行。在开始读取数据行之前,不必获取所有索引元组
The MRR optimization is not supported with secondary indexes created on virtual generated columns. 在虚拟生成列上创建的二级索引不支持MRR优化。InnoDB
supports secondary indexes on virtual generated columns.InnoDB
支持虚拟生成列上的辅助索引。
The following scenarios illustrate when MRR optimization can be advantageous:以下场景说明了MRR优化何时具有优势:
Scenario A: MRR can be used for 场景A:MRR可用于InnoDB
and MyISAM
tables for index range scans and equi-join operations.InnoDB
和MyISAM
表,用于索引范围扫描和等连接操作。
A portion of the index tuples are accumulated in a buffer.索引元组的一部分累积在缓冲区中。
The tuples in the buffer are sorted by their data row ID.缓冲区中的元组按其数据行ID排序。
Data rows are accessed according to the sorted index tuple sequence.根据排序的索引元组序列访问数据行。
Scenario B: MRR can be used for 场景B:MRR可用于NDB
tables for multiple-range index scans or when performing an equi-join by an attribute.NDB
表,用于多个范围索引扫描或通过属性执行等联接。
A portion of ranges, possibly single-key ranges, is accumulated in a buffer on the central node where the query is submitted.一部分范围(可能是单键范围)累积在提交查询的中心节点上的缓冲区中。
The ranges are sent to the execution nodes that access data rows.范围被发送到访问数据行的执行节点。
The accessed rows are packed into packages and sent back to the central node.访问的行被打包到包中并发送回中心节点。
The received packages with data rows are placed in a buffer.接收到的包含数据行的包被放置在缓冲区中。
Data rows are read from the buffer.从缓冲区读取数据行。
When MRR is used, the 当使用Extra
column in EXPLAIN
output shows Using MRR
.MRR
时,EXPLAIN
输出中的额外列显示USING MRR
。
如果不需要访问完整的表行来生成查询结果,InnoDB
and MyISAM
do not use MRR if full table rows need not be accessed to produce the query result. InnoDB
和MyISAM
不使用MRR。This is the case if results can be produced entirely on the basis on information in the index tuples (through a covering index); MRR provides no benefit.如果可以完全基于索引元组中的信息(通过覆盖索引)生成结果,则会出现这种情况;MRR没有任何好处。
Two 两个optimizer_switch
system variable flags provide an interface to the use of MRR optimization. optimizer_switch
系统变量标志提供了使用MRR优化的接口。The mrr
flag controls whether MRR is enabled. mrr
标志控制是否启用MRR。If 如果启用了mrr
is enabled (on
), the mrr_cost_based
flag controls whether the optimizer attempts to make a cost-based choice between using and not using MRR (on
) or uses MRR whenever possible (off
). mrr
(on
),则mrr_cost_based
标志控制优化器是否尝试在使用和不使用MRR(on
)或尽可能使用MRR(off
)之间做出基于成本的选择。By default, 默认情况下,mrr
is on
and mrr_cost_based
is on
. mrr
处于on
状态,mrr_cost_based
处于on
状态。See Section 8.9.2, “Switchable Optimizations”.参见第8.9.2节,“可切换优化”。
For MRR, a storage engine uses the value of the 对于MRR,存储引擎使用read_rnd_buffer_size
system variable as a guideline for how much memory it can allocate for its buffer. read_rnd_buffer_size
系统变量的值作为它可以为其缓冲区分配多少内存的准则。The engine uses up to 引擎最多使用read_rnd_buffer_size
bytes and determines the number of ranges to process in a single pass.read_rnd_buffer_size
的字节,并确定要在单个过程中处理的范围数。