10.2.1.11 多范围读优化
使用次要索引进行范围扫描可以在大型表中导致许多随机磁盘访问,尤其是表未被存储引擎缓存时。Disk-Sweep Multi-Range Read(MRR)优化尝试通过首先只扫描索引,收集相关行的键,然后对键进行排序,最后使用主键顺序从基础表中检索行,以减少随机磁盘访问的数量。Disk-sweep MRR 的motivation 是为了减少随机磁盘访问,而是实现更sequential 的基础表数据扫描。
Multi-Range Read 优化提供以下益处:
-
MRR 允许数据行以顺序方式而不是随机顺序被访问,基于索引元组。服务器获取满足查询条件的索引元组,按照数据行ID顺序对它们进行排序,然后使用排序后的元组来检索数据行,以提高数据访问效率和降低成本。
-
MRR 允许批处理请求以获取键访问为操作所需的数据行,例如范围索引扫描和使用索引进行join 的等值连接。MRR 迭代遍历索引范围,以获取满足条件的索引元组。随着结果累积,它们将被用于访问相应的数据行。无需在开始读取数据行之前获取所有索引元组。
MRR 优化不支持使用虚拟生成列创建的次要索引。InnoDB
支持使用虚拟生成列创建的次要索引。
以下场景展示了 MRR 优化何时可以有利:
场景A:MRR可以用于InnoDB
和MyISAM
表的索引范围扫描和等值连接操作。
-
缓冲区中累积了一部分索引元组。
-
缓冲区中的索引元组按数据行ID排序。
-
根据排序后的索引元组顺序访问数据行。
场景B:MRR可以用于NDB
表的多范围索引扫描或执行等值连接操作时,通过属性。
-
可能是单键范围的部分范围在中央节点上查询提交的缓冲区中累积。
-
范围被发送到访问数据行的执行节点。
-
访问的行被打包成包并发送回中央节点。
-
收到的包中的数据行被放置在缓冲区中。
-
从缓冲区中读取数据行。
当使用MRR时,EXPLAIN
输出的Extra
列显示Using MRR
。
InnoDB
和MyISAM
不使用MRR,如果查询结果可以完全基于索引元组信息生产(通过覆盖索引),MRR无益处。
两个optimizer_switch
系统变量标志提供了MRR优化的接口。标志mrr
控制是否启用MRR。如果mrr
已启用(on
),则标志mrr_cost_based
控制优化器是否尝试基于成本进行选择,使用或不使用MRR(on
),或者总是使用MRR(off
)。默认情况下,mrr
设置为on
,而mrr_cost_based
也设置为on
。请参阅第10.9.2节,“可切换优化”.
对于MRR,存储引擎使用read_rnd_buffer_size
系统变量的值作为其缓冲区分配内存的指南。引擎将使用最多read_rnd_buffer_size
字节,并确定单个pass中要处理的范围数。