多范围读取优化
跳到导航
跳到搜索
在使用二级索引进行范围扫描时,如果表很大且未存储在存储引擎的缓存中,可能会导致许多随机磁盘访问到基表。通过磁盘扫描的多范围读取(MRR)优化,MySQL试图通过首先仅扫描索引并收集相关行的键来减少范围扫描的随机磁盘访问次数。然后,对键进行排序,最后按照主键的顺序从基表中检索行。磁盘扫描的MRR的动机是减少随机磁盘访问次数,而是实现对基表数据的更顺序的扫描。
多范围读取优化提供以下好处:
- MRR使数据行能够按顺序访问,而不是随机访问,基于索引元组。服务器获取满足查询条件的一组索引元组,按照数据行ID顺序对它们进行排序,并使用排序后的元组按顺序检索数据行。这使得数据访问更高效、更廉价。
- MRR使得批量处理对键访问的请求成为可能,对于需要通过索引元组访问数据行的操作,例如范围索引扫描和使用索引进行连接的等值连接。MRR迭代一系列索引范围以获取符合条件的索引元组。随着这些结果的累积,它们被用于访问相应的数据行。在开始读取数据行之前不需要获取所有索引元组。
MRR优化不支持在虚拟生成列上创建的二级索引。InnoDB支持对虚拟生成列创建二级索引。
以下场景说明了MRR优化的优势:
- 场景A:对于InnoDB和MyISAM表,MRR可用于索引范围扫描和等值连接操作。
- 部分索引元组被累积在缓冲区中。
- 缓冲区中的元组按照它们的数据行ID进行排序。
- 根据排序后的索引元组序列访问数据行。
- 场景B:对于NDB表,MRR可用于多范围索引扫描,或者通过属性进行等值连接。
- 部分范围(可能是单键范围)在查询提交的中央节点上累积在缓冲区中。
- 范围被发送到访问数据行的执行节点。
- 访问的行被打包成数据包并发送回中央节点。
- 接收到的带有数据行的数据包被放置在缓冲区中。
- 从缓冲区读取数据行。
当使用MRR时,EXPLAIN输出中的Extra列显示为Using MRR。
如果不需要访问完整的表行来生成查询结果,InnoDB和MyISAM不会使用MRR。如果结果可以完全基于索引元组中的信息(通过覆盖索引)生成,则MRR不会提供任何好处。
两个optimizer_switch系统变量标志提供了使用MRR优化的接口。mrr标志控制是否启用MRR。如果mrr启用(开启),则mrr_cost_based标志控制优化器是否尝试在使用和不使用MRR之间进行基于成本的选择(启用),或者尽可能使用MRR(关闭)。默认情况下,mrr为开启状态,mrr_cost_based为开启状态。
对于MRR,存储引擎使用read_rnd_buffer_size系统变量的值作为其缓冲区可以分配多少内存的指导。该引擎使用最多read_rnd_buffer_size字节,并确定在单次操作中要处理的范围数量。