From ac43337b3f472119230258bbb2ebaf7540826c6e Mon Sep 17 00:00:00 2001 From: asahi Date: Mon, 17 Feb 2025 12:56:00 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=85=E8=AF=BBinnodb=20mutlti-range=20read?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mysql/mysql文档/mysql_索引.md | 45 ++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/mysql/mysql文档/mysql_索引.md b/mysql/mysql文档/mysql_索引.md index a6f86fc..04a90ce 100644 --- a/mysql/mysql文档/mysql_索引.md +++ b/mysql/mysql文档/mysql_索引.md @@ -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`. +