1
1
---
2
- title : 用 EXPLAIN 查看开启 IndexMerge 的 SQL 执行计划
2
+ title : 用 EXPLAIN 查看索引合并的 SQL 执行计划
3
3
summary : 了解 TiDB 中 EXPLAIN 语句返回的执行计划信息。
4
4
---
5
5
6
- # 用 EXPLAIN 查看开启 IndexMerge 的 SQL 执行计划
6
+ # 用 EXPLAIN 查看索引合并的 SQL 执行计划
7
7
8
- ` IndexMerge ` 是 TiDB v4.0 中引入的一种对表的新访问方式 。在这种访问方式下,TiDB 优化器可以选择对一张表使用多个索引,并将每个索引的返回结果进行合并。在某些场景下,这种访问方式能够减少大量不必要的数据扫描,提升查询的执行效率。
8
+ 索引合并是从 TiDB v4.0 起引入的一种新的表访问方式 。在这种访问方式下,TiDB 优化器可以选择对一张表使用多个索引,并将每个索引的返回结果进行合并。在某些场景下,这种访问方式能够减少大量不必要的数据扫描,提升查询的执行效率。
9
9
10
10
``` sql
11
- EXPLAIN SELECT * from t where a = 1 or b = 1 ;
11
+ EXPLAIN SELECT * FROM t WHERE a = 1 OR b = 1 ;
12
12
+ -- -----------------------+----------+-----------+---------------+--------------------------------------+
13
13
| id | estRows | task | access object | operator info |
14
14
+ -- -----------------------+----------+-----------+---------------+--------------------------------------+
15
15
| TableReader_7 | 8000 .00 | root | | data:Selection_6 |
16
16
| └─Selection_6 | 8000 .00 | cop[tikv] | | or (eq(test .t .a, 1 ), eq(test .t .b, 1 )) |
17
17
| └─TableFullScan_5 | 10000 .00 | cop[tikv] | table:t | keep order:false, stats:pseudo |
18
18
+ -- -----------------------+----------+-----------+---------------+--------------------------------------+
19
- set @@tidb_enable_index_merge = 1 ;
20
- explain select * from t use index(idx_a, idx_b) where a > 1 or b > 1 ;
19
+ EXPLAIN SELECT /* + USE_INDEX_MERGE(t) */ * FROM t WHERE a > 1 OR b > 1 ;
21
20
+ -- ------------------------------+---------+-----------+-------------------------+------------------------------------------------+
22
21
| id | estRows | task | access object | operator info |
23
22
+ -- ------------------------------+---------+-----------+-------------------------+------------------------------------------------+
@@ -28,21 +27,18 @@ explain select * from t use index(idx_a, idx_b) where a > 1 or b > 1;
28
27
+ -- ------------------------------+---------+-----------+-------------------------+------------------------------------------------+
29
28
```
30
29
31
- 例如,在上述示例中,过滤条件是使用 ` OR ` 条件连接的 ` WHERE ` 子句。在启用 ` IndexMerge ` 前 ,每个表只能使用一个索引,不能将 ` a = 1 ` 下推到索引 ` a ` ,也不能将 ` b = 1 ` 下推到索引 ` b ` 。当 ` t ` 中存在大量数据时,全表扫描的效率会很低。针对这类场景,TiDB 引入了对表的新访问方式 ` IndexMerge ` 。
30
+ 例如,在上述示例中,过滤条件是使用 ` OR ` 条件连接的 ` WHERE ` 子句。在启用索引合并前 ,每个表只能使用一个索引,不能将 ` a = 1 ` 下推到索引 ` a ` ,也不能将 ` b = 1 ` 下推到索引 ` b ` 。当 ` t ` 中存在大量数据时,全表扫描的效率会很低。针对这类场景,TiDB 引入了对表的新访问方式:索引合并 。
32
31
33
- 在 ` IndexMerge ` 访问方式下 ,优化器可以选择对一张表使用多个索引,并将每个索引的返回结果进行合并,生成以上示例中后一个 ` IndexMerge ` 的执行计划 。此时的 ` IndexMerge_16 ` 算子有三个子节点,其中 ` IndexRangeScan_13 ` 和 ` IndexRangeScan_14 ` 根据范围扫描得到符合条件的所有 ` RowID ` ,再由 ` TableRowIDScan_15 ` 算子根据这些 ` RowID ` 精确地读取所有满足条件的数据。
32
+ 在索引合并访问方式下 ,优化器可以选择对一张表使用多个索引,并将每个索引的返回结果进行合并,生成以上示例中后一个执行计划 。此时的 ` IndexMerge_16 ` 算子有三个子节点,其中 ` IndexRangeScan_13 ` 和 ` IndexRangeScan_14 ` 根据范围扫描得到符合条件的所有 ` RowID ` ,再由 ` TableRowIDScan_15 ` 算子根据这些 ` RowID ` 精确地读取所有满足条件的数据。
34
33
35
34
其中对于 ` IndexRangeScan ` /` TableRangeScan ` 一类按范围进行的扫表操作,` EXPLAIN ` 表中 ` operator info ` 列相比于其他扫表操作,多了被扫描数据的范围这一信息。比如上面的例子中,` IndexRangeScan_13 ` 算子中的 ` range:(1,+inf] ` 这一信息表示该算子扫描了从 1 到正无穷这个范围的数据。
36
35
37
36
> ** 注意:**
38
37
>
39
- > 目前,TiDB 的 ` IndexMerge ` 特性在 TiDB 4.0.0-rc.1 版本中默认关闭。同时 4.0 版本中的 ` IndexMerge ` 目前支持的场景仅限于析取范式(` or ` 连接的表达式),暂不支持合取范式(` and ` 连接的表达式)。开启 ` IndexMerge ` 特性有以下方法:
40
- >
41
- > - 设置系统变量 ` tidb_enable_index_merge=1 ` ;
42
- >
43
- > - 在查询中使用 SQL 优化器 Hint [ ` USE_INDEX_MERGE ` ] ( /optimizer-hints.md#use_index_merget1_name-idx1_name--idx2_name- ) 。
44
- >
45
- > SQL Hint 的优先级高于系统变量。
38
+ > - TiDB 的索引合并特性在 v5.4.0 及之后的版本默认开启,即 [ ` tidb_enable_index_merge ` ] ( /system-variables.md#tidb_enable_index_merge-从-v40-版本开始引入 ) 为 ` ON ` 。
39
+ > - 如果查询中使用了 SQL 优化器 Hint [ ` USE_INDEX_MERGE ` ] ( /optimizer-hints.md#use_index_merget1_name-idx1_name--idx2_name- ) ,无论 ` tidb_enable_index_merge ` 开关是否开启,都会强制使用索引合并特性。当过滤条件中有无法下推的表达式时,必须使用 Hint [ ` USE_INDEX_MERGE ` ] ( /optimizer-hints.md#use_index_merget1_name-idx1_name--idx2_name- ) 才能开启索引合并。
40
+ > - 索引合并目前仅支持析取范式(` or ` 连接的表达式),不支持合取范式(` and ` 连接的表达式)。
41
+ > - 索引合并目前无法在临时表上使用。
46
42
47
43
## 其他类型查询的执行计划
48
44
0 commit comments