阅读innodb mutlti-range read文档

This commit is contained in:
asahi
2025-02-17 12:56:00 +08:00
parent e9000354db
commit ac43337b3f

View File

@@ -25,6 +25,12 @@
- [Use index](#use-index)
- [Multi-Range Read](#multi-range-read)
- [multi-range read优势](#multi-range-read优势)
- [范围查询和join查询优化](#范围查询和join查询优化)
- [拆分键值对](#拆分键值对)
- [未开启MRR](#未开启mrr)
- [开启MRR优化](#开启mrr优化)
- [mrr控制](#mrr控制)
- [read\_rnd\_buffer\_size](#read_rnd_buffer_size)
# innodb索引与算法
@@ -313,9 +319,46 @@ mysql支持Multi-Range Read优化用于减少随机的磁盘访问将随
mutli-range read优化适用于`range, ref, eq_ref`类型的查询。
### multi-range read优势
- MBR能够令数据访问变得较为顺序在查询辅助索引时对于得到的查询结果按照主键进行排序并按照主键排序的顺序进行书签查找
- MRR能够令数据访问变得较为顺序在查询辅助索引时对于得到的查询结果按照主键进行排序并按照主键排序的顺序进行书签查找
- 减少缓冲池中页被替换的次数
- 批量处理对于key的查询操作
### 范围查询和join查询优化
对于innodb的范围查询和join查询MRR工作方式如下
- 将查询到的辅助索引键值存放在缓冲中,此时缓存中的数据按照辅助索引排序
- 将缓存中的键值按照rowId进行排序
- 根据rowId的排序来实际访问数据文件
> 当innodb的缓冲池不足以存放表中所有数据时频繁的离散读写会导致缓冲池中的页被换出又被不断读入。
>
> `如果按照主键顺序进行访问,可以将该类行为降至最低,页面不会被换出缓冲区后又被读入`。
### 拆分键值对
除了上述优化外对某些范围查询mrr还能够进行拆分优化这样在拆分过程中直接能过滤掉一些不符合查询条件的数据。
例如:
```sql
select * from t where key_part1 >= 1000 and key_part1 < 2000 and key_part2 = 1000;
```
表t存在`(key_part1, key_part2)`的联合索引。
#### 未开启MRR
如果未开启mrr那么此时查询类型为`RANGE`mysql优化器会将key_part位于`[1000, 2000)`范围内的全部数据都取出即是key_part2不为1000。在去除后再按key_part2条件对取出数据进行过滤。
> 这将会导致有大量无用数据被取出。如果存在大量数据且key_part2不为1000那么使用mrr将会有大量性能提升。
#### 开启MRR优化
在使用了MRR优化后优化器会先对查询条件进行拆分`key_part1 >= 1000 and key_part1 < 2000 and key_part2 = 1000`条件拆分为`(1000, 1000), (1001, 1000), ..., (1999, 1000)`,在根据拆分后的条件进行查询。
#### mrr控制
是否开启mrr可以通过参数`optimizer_switch`中的flag来控制当mrr为`on`代表启用mrr优化。
`mrr_cost_based`标记代表`是否通过cost based的方式来选择是否启用mrr`
如果将`mrr`设置为`on``mrr_cost_based`设置为`off`代表总是启用mrr优化。
#### read_rnd_buffer_size
`read_rnd_buffer_size`用来控制键值的缓冲区大小当大于该值时则执行器则对已经缓存的数据根据rowId来进行排序并通过rowId来获取数据。该值默认为`256K`.