From 7ea206ef94fa7a8bc077b1586ee972aa42fd98a1 Mon Sep 17 00:00:00 2001 From: Chao Wang Date: Wed, 24 Sep 2025 17:27:37 +0800 Subject: [PATCH 1/2] Add index lookup push down content --- optimizer-hints.md | 40 ++++++++++++++++++++++++++++++++++++++++ system-variables.md | 9 +++++++++ 2 files changed, 49 insertions(+) diff --git a/optimizer-hints.md b/optimizer-hints.md index 45865c95dd3d..2f90b72c46c1 100644 --- a/optimizer-hints.md +++ b/optimizer-hints.md @@ -477,6 +477,46 @@ EXPLAIN SELECT /*+ NO_ORDER_INDEX(t, a) */ a FROM t ORDER BY a LIMIT 10; 和 `ORDER_INDEX` Hint 的示例相同,优化器对该查询会生成两类计划:`Limit + IndexScan(keep order: true)` 和 `TopN + IndexScan(keep order: false)`,当使用了 `NO_ORDER_INDEX` Hint,优化器会选择后一种不按照顺序读取索引的计划。 +### INDEX_LOOKUP_PUSHDOWN(t1_name, idx1_name [, idx2_name ...]) + +`INDEX_LOOKUP_PUSHDOWN(t1_name, idx1_name [, idx2_name ...])` 提示优化器对指定表仅使用给出的索引,并下推 `IndexLookUp` 算子到 TiKV。 + +以下示例展示了使用此 Hint 的查询计划: + +{{< copyable "sql" >}} + +```sql +CREATE TABLE t1(a INT, b INT, key(a)); +EXPLAIN SELECT /*+ INDEX_LOOKUP_PUSHDOWN(t1, a) */ a, b FROM t1; +``` + +```sql ++-----------------------------+----------+-----------+----------------------+--------------------------------+ +| id | estRows | task | access object | operator info | ++-----------------------------+----------+-----------+----------------------+--------------------------------+ +| IndexLookUp_7 | 10000.00 | root | | | +| ├─LocalIndexLookUp(Build) | 10000.00 | cop[tikv] | | index handle offsets:[1] | +| │ ├─IndexFullScan_5(Build) | 10000.00 | cop[tikv] | table:t1, index:a(a) | keep order:false, stats:pseudo | +| │ └─TableRowIDScan_8(Probe) | 10000.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo | +| └─TableRowIDScan_6(Probe) | 0.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo | ++-----------------------------+----------+-----------+----------------------+--------------------------------+ +``` + +在启用 `INDEX_LOOKUP_PUSHDOWN` hint 后,下推计划中的最外层 Build 算子会变为 `LocalIndexLookUp`。这意味着 TiKV 在扫描索引的同时,会尝试在本地回表查询对应的行数据。然而,由于索引和行数据可能分布在不同的 Region,下推请求无法保证覆盖所有目标行。因此,TiDB 端仍需保留 `TableRowIDScan`,用于补充查询那些下推无法命中的行。此 hint 受系统变量 [`tidb_enable_index_lookup_pushdown`](/system-variables.md#tidb_enable_index_lookup_pushdown-从-v90-版本开始引入) 影响。 + +`INDEX_LOOKUP_PUSHDOWN` 当前的使用限制如下: + +- 不支持缓存表(cache table)和临时表。 +- 暂不支持分区表查询。 +- 暂不支持复合主键或主键为非整型的聚簇索引表。 +- 暂不支持除 `REPEATABLE-READ` 之外的其他隔离级别。 +- 暂不支持[多值索引](/choose-index.md#使用多值索引)的查询。 +- 暂不支持 [Follower Read](/follower-read.md)。 +- 暂不支持 [Stale Read](/stale-read.md) 或 [使用 `tidb_snapshot` 来读取历史数据](/read-historical-data.md)。 +- 下推的 `LocalIndexLookUp` 算子暂不支持 keep order。若执行计划中包含基于索引列的 `ORDER BY`,则会退化为普通的 `LocalIndexLookUp` 查询。 +- 下推的 `LocalIndexLookUp` 算子暂不支持以分页 (paging)方式发送 Coprocessor 请求。 +- 下推的 `LocalIndexLookUp` 算子暂不支持对[下推计算结果进行缓存](/coprocessor-cache.md) + ### AGG_TO_COP() `AGG_TO_COP()` 提示优化器将指定查询块中的聚合函数下推到 coprocessor。如果优化器没有下推某些适合下推的聚合函数,建议尝试使用。例如: diff --git a/system-variables.md b/system-variables.md index 71dc3041fec3..57db9cb4378a 100644 --- a/system-variables.md +++ b/system-variables.md @@ -2051,6 +2051,15 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1; - 默认值:`OFF` - 这个变量用来控制 `PLAN REPLAYER CAPTURE` 抓取的内容是否默认带历史统计信息。默认值为 `OFF`,表示默认不带历史统计信息。 +### `tidb_enable_index_lookup_pushdown` 从 v9.0 版本开始引入 + +- 作用域:SESSION | GLOBAL +- 是否持久化到集群:是 +- 是否受 Hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value) 控制:否 +- 类型:布尔型 +- 默认值:`OFF` +- 这个变量用于控制是否启用 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,也不会生效。 + ### `tidb_enable_index_merge` 从 v4.0 版本开始引入 > **注意:** From 85712ca6bb1c2a9d685bef61ff7adbbb7391a54a Mon Sep 17 00:00:00 2001 From: Chao Wang Date: Thu, 16 Oct 2025 10:20:14 +0800 Subject: [PATCH 2/2] remove sys var --- optimizer-hints.md | 2 +- system-variables.md | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/optimizer-hints.md b/optimizer-hints.md index 2f90b72c46c1..caea33ab0a05 100644 --- a/optimizer-hints.md +++ b/optimizer-hints.md @@ -502,7 +502,7 @@ EXPLAIN SELECT /*+ INDEX_LOOKUP_PUSHDOWN(t1, a) */ a, b FROM t1; +-----------------------------+----------+-----------+----------------------+--------------------------------+ ``` -在启用 `INDEX_LOOKUP_PUSHDOWN` hint 后,下推计划中的最外层 Build 算子会变为 `LocalIndexLookUp`。这意味着 TiKV 在扫描索引的同时,会尝试在本地回表查询对应的行数据。然而,由于索引和行数据可能分布在不同的 Region,下推请求无法保证覆盖所有目标行。因此,TiDB 端仍需保留 `TableRowIDScan`,用于补充查询那些下推无法命中的行。此 hint 受系统变量 [`tidb_enable_index_lookup_pushdown`](/system-variables.md#tidb_enable_index_lookup_pushdown-从-v90-版本开始引入) 影响。 +在启用 `INDEX_LOOKUP_PUSHDOWN` hint 后,下推计划中的最外层 Build 算子会变为 `LocalIndexLookUp`。这意味着 TiKV 在扫描索引的同时,会尝试在本地回表查询对应的行数据。然而,由于索引和行数据可能分布在不同的 Region,下推请求无法保证覆盖所有目标行。因此,TiDB 端仍需保留 `TableRowIDScan`,用于补充查询那些下推无法命中的行。 `INDEX_LOOKUP_PUSHDOWN` 当前的使用限制如下: diff --git a/system-variables.md b/system-variables.md index 57db9cb4378a..71dc3041fec3 100644 --- a/system-variables.md +++ b/system-variables.md @@ -2051,15 +2051,6 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1; - 默认值:`OFF` - 这个变量用来控制 `PLAN REPLAYER CAPTURE` 抓取的内容是否默认带历史统计信息。默认值为 `OFF`,表示默认不带历史统计信息。 -### `tidb_enable_index_lookup_pushdown` 从 v9.0 版本开始引入 - -- 作用域:SESSION | GLOBAL -- 是否持久化到集群:是 -- 是否受 Hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value) 控制:否 -- 类型:布尔型 -- 默认值:`OFF` -- 这个变量用于控制是否启用 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,也不会生效。 - ### `tidb_enable_index_merge` 从 v4.0 版本开始引入 > **注意:**