8.2.1.11-多区间读取(MRR)优化

如果表的数量太大,存储引擎的缓存不足以容纳所有表数据,通过对二级索引进行区间扫描来读取多行记录,在回表查询时会产生很多随机磁盘I/O。有了磁盘清理多区间扫描(MRR)优化,mysql尝试去先扫描二级索引,获取相关记得key。然后相关的key被排序,然后按照主键的顺序从基础表上读取数据。MRR技术的本意是为了减少磁盘随机访问,而不是对基础表的更序列化的磁盘访问。

MRR优化右以下好处:

  • MRR使通过索引元组访问数据记录时,由随机访问变为顺序访问。数据库服务器获取一个满足查询条件索引元组集合,根据记录id进行排序,然后按照顺序读取记录。这使得数据访问更加高效。
  • MRR使得通过索引元组回表查询的操作(如区间索引扫描,通过索引进行等值连接)可以批量处理。MRR循环迭代处理一系列索引区间来获取满足条件的索引元组。当这些数据累积后,就会被用来获取相关的记录。不用等到获取到所有的索引元组后再回表查询数据记录。

MRR不适用于虚拟列上建立的索引。InnoDB支持在虚拟列上建立索引。

下列场景中MRR会被使用:

场景A:InnoDB和MyISAM表,使用MRR来进行索引区间扫描和等值连接操作。

  1. 一部分索引元组被聚集在buffer中。
  2. 根据记录id对buffer中的索引元组进行排序。
  3. 根据排序号的索引元组来回表查询。

场景B: NDB表,使用MRR来进行多区间索引扫描,或者是进行等值连接。

  1. 一部分区间,可能是单列区间,在buffer中累积。
  2. 这些区间被发送到执行节点获取记录数据。
  3. 获取到的记录被打包返回中央节点。
  4. 收到数据记录后,将其放到一个buffer中。
  5. 从buffer中读取记录。

当使用MRR时,explain输出中的Extra列会显示Using MRR。

如果不需要回表查询完整的数据记录,InnoDB和MyISAM不会使用MRR。应为这种情况下查询需要的所有数据都在二级索引上(覆盖索引)。MRR提供不了额外的好处。

有两个optimizer_switch系统变量标志会影响MRR优化。mrr控制是否使用MRR。如果mrr是开启的(on),mrr_cost_based标志控制优化器是否基于成本选择是否使用MRR。mrr和mrr_cost_based默认都是on。见章节8.9.2 “Switchable Optimizations”。