Skip to content

Commit 476f9c7

Browse files
committed
Add index lookup push down content
1 parent 288d1f5 commit 476f9c7

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

optimizer-hints.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,44 @@ EXPLAIN SELECT /*+ NO_ORDER_INDEX(t, a) */ a FROM t ORDER BY a LIMIT 10;
477477

478478
`ORDER_INDEX` Hint 的示例相同,优化器对该查询会生成两类计划:`Limit + IndexScan(keep order: true)``TopN + IndexScan(keep order: false)`,当使用了 `NO_ORDER_INDEX` Hint,优化器会选择后一种不按照顺序读取索引的计划。
479479

480+
### INDEX_LOOKUP_PUSHDOWN(t1_name, idx1_name [, idx2_name ...])
481+
482+
`INDEX_LOOKUP_PUSHDOWN(t1_name, idx1_name [, idx2_name ...])` 提示优化器对指定表仅使用给出的索引,并下推 `IndexLookUp` 算子到 TiKV。
483+
484+
以下示例展示了使用此 Hint 的查询计划:
485+
486+
{{< copyable "sql" >}}
487+
488+
```sql
489+
CREATE TABLE t1(a INT, b INT, key(a));
490+
EXPLAIN SELECT /*+ INDEX_LOOKUP_PUSHDOWN(t1, a) */ a, b FROM t1;
491+
```
492+
493+
```sql
494+
+-----------------------------+----------+-----------+----------------------+--------------------------------+
495+
| id | estRows | task | access object | operator info |
496+
+-----------------------------+----------+-----------+----------------------+--------------------------------+
497+
| IndexLookUp_7 | 10000.00 | root | | |
498+
| ├─LocalIndexLookUp(Build) | 10000.00 | cop[tikv] | | index handle offsets:[1] |
499+
| │ ├─IndexFullScan_5(Build) | 10000.00 | cop[tikv] | table:t1, index:a(a) | keep order:false, stats:pseudo |
500+
| │ └─TableRowIDScan_8(Probe) | 10000.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo |
501+
| └─TableRowIDScan_6(Probe) | 0.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo |
502+
+-----------------------------+----------+-----------+----------------------+--------------------------------+
503+
```
504+
505+
在启用 `INDEX_LOOKUP_PUSHDOWN` hint 后,下推计划中的最外层 Build 算子会变为 `IndexLookUp`。这意味着 TiKV 在扫描索引的同时,会尝试在本地回表查询对应的行数据。然而,由于索引和行数据可能分布在不同的 Region,下推请求无法保证覆盖所有目标行。因此,TiDB 端仍需保留 `TableRowIDScan`,用于补充查询那些下推无法命中的行。此 hint 受系统变量 [`tidb_enable_index_lookup_pushdown`](/system-variables.md#tidb_enable_index_lookup_pushdown-从-v90-版本开始引入) 影响。
506+
507+
`INDEX_LOOKUP_PUSHDOWN` 当前的使用限制如下:
508+
509+
- 不支持缓存表(cache table)和临时表。
510+
- 暂不支持分区表查询。
511+
- 暂不支持复合主键或主键为非整型的聚簇索引表。
512+
- 暂不支持除 `REPEATABLE-READ` 之外的其他隔离级别。
513+
- 暂不支持 [Follower Read](/follower-read.md)
514+
- 暂不支持 [Stale Read](/stale-read.md)[使用 `tidb_snapshot` 来读取历史数据](/read-historical-data.md)
515+
- 下推的 `IndexLookUp` 算子暂不支持 keep order。若执行计划中包含基于索引列的 `ORDER BY`,则会退化为普通的 `IndexLookUp` 查询。
516+
- 下推的 `IndexLookUp` 算子暂不支持以分页 (paging)方式发送 Coprocessor 请求。
517+
480518
### AGG_TO_COP()
481519

482520
`AGG_TO_COP()` 提示优化器将指定查询块中的聚合函数下推到 coprocessor。如果优化器没有下推某些适合下推的聚合函数,建议尝试使用。例如:

system-variables.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,15 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1;
20512051
- 默认值:`OFF`
20522052
- 这个变量用来控制 `PLAN REPLAYER CAPTURE` 抓取的内容是否默认带历史统计信息。默认值为 `OFF`,表示默认不带历史统计信息。
20532053

2054+
### `tidb_enable_index_lookup_pushdown` <span class="version-mark">从 v9.0 版本开始引入</span>
2055+
2056+
- 作用域:SESSION | GLOBAL
2057+
- 是否持久化到集群:是
2058+
- 是否受 Hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value) 控制:否
2059+
- 类型:布尔型
2060+
- 默认值:`OFF`
2061+
- 这个变量用于控制是否启用 IndexLookUp 下推。当变量值为 `ON` 且查询中显式使用了 hint [`INDEX_LOOKUP_PUSHDOWN`](/optimizer-hints.md#index_lookup_pushdownt1_name-idx1_name--idx2_name-) 时,TiDB 会将相应的 IndexLookUp 查询下推至 TiKV 执行。若变量值为 `OFF`,则即使在查询中指定了 `INDEX_LOOKUP_PUSHDOWN` Hint,也不会生效。
2062+
20542063
### `tidb_enable_index_merge` <span class="version-mark">从 v4.0 版本开始引入</span>
20552064

20562065
> **注意:**

0 commit comments

Comments
 (0)