Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

variable: add document about lazy cursor fetch and its variable #18073

Merged
merged 12 commits into from
Aug 15, 2024
10 changes: 7 additions & 3 deletions best-practices/java-app-best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,19 @@ Java 应用尽管可以选择在不同的框架中封装,但在最底层一般

在 JDBC 中通常有以下两种处理方式:

- 设置 [`FetchSize` 为 `Integer.MIN_VALUE`](https://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html#ResultSet) 让客户端不缓存,客户端通过 StreamingResult 的方式从网络连接上流式读取执行结果。
- 方式一:设置 [`FetchSize` 为 `Integer.MIN_VALUE`](https://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html#ResultSet) 让客户端不缓存,客户端通过 StreamingResult 的方式从网络连接上流式读取执行结果。

使用流式读取数据时,需要将 `resultset` 读取完成或 close 后,才能继续使用该语句进行下次查询,否则会报错 `No statements may be issued when any streaming result sets are open and in use on a given connection. Ensure that you have called .close() on any active streaming result sets before attempting more queries.`。

如果需要在 `resultset` 读取完成或 close 前进行查询避免上述报错,可在 URL 中添加配置参数 `clobberStreamingResults=true`,这样会自动 close `resultset`,但之前流式查询未被读取的结果集会丢失。

- 使用 Cursor Fetch,首先需[设置 `FetchSize`](http://makejavafaster.blogspot.com/2015/06/jdbc-fetch-size-performance.html) 为正整数,且在 JDBC URL 中配置 `useCursorFetch = true`。
- 方式二:使用 Cursor Fetch,首先需[设置 `FetchSize`](http://makejavafaster.blogspot.com/2015/06/jdbc-fetch-size-performance.html) 为正整数,且在 JDBC URL 中配置 `useCursorFetch = true`。

TiDB 中同时支持两种方式,但更推荐使用第一种将 `FetchSize` 设置为 `Integer.MIN_VALUE` 的方式,比第二种功能实现更简单且执行效率更高。
TiDB 同时支持以上两种方式,但更推荐使用第一种将 `FetchSize` 设置为 `Integer.MIN_VALUE` 的方式,比第二种功能实现更简单且执行效率更高。

对于第二种方式,TiDB 会先将所有数据加载到 TiDB 节点上,然后根据 `FetchSize` 依次返回给客户端。因此,通常会比第一种方式使用更多内存。如果将 [`tidb_enable_tmp_storage_on_oom`](/system-variables.md#tidb_enable_tmp_storage_on_oom) 设置为 `ON`,可能会触发落盘临时将结果写入硬盘。

如果系统变量 [`tidb_enable_lazy_cursor_fetch`](/system-variables.md#tidb_enable_lazy_cursor_fetch-从-v830-版本开始引入) 设置为 `ON`,TiDB 将尝试仅在客户端请求数据时读取部分数据,以使用更少的内存。更多信息和使用限制,参见系统变量 [`tidb_enable_lazy_cursor_fetch`](/system-variables.md#tidb_enable_lazy_cursor_fetch-从-v830-版本开始引入) 的详细描述。

### MySQL JDBC 参数

Expand Down
10 changes: 7 additions & 3 deletions develop/dev-guide-connection-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,14 @@ Java 应用尽管可以选择在不同的框架中封装,但在最底层一般

在 JDBC 中通常有以下两种处理方式:

- 设置 [**FetchSize** 为 `Integer.MIN_VALUE`](https://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html#ResultSet) 让客户端不缓存,客户端通过 StreamingResult 的方式从网络连接上流式读取执行结果。
- 使用 Cursor Fetch,首先需[设置 **FetchSize**](http://makejavafaster.blogspot.com/2015/06/jdbc-fetch-size-performance.html) 为正整数,且在 JDBC URL 中配置 `useCursorFetch = true`。
- 方式一:设置 [**FetchSize** 为 `Integer.MIN_VALUE`](https://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html#ResultSet) 让客户端不缓存,客户端通过 StreamingResult 的方式从网络连接上流式读取执行结果。
- 方式二:使用 Cursor Fetch,首先需[设置 **FetchSize**](http://makejavafaster.blogspot.com/2015/06/jdbc-fetch-size-performance.html) 为正整数,且在 JDBC URL 中配置 `useCursorFetch = true`。

TiDB 中同时支持两种方式,但更推荐使用第一种将 **FetchSize** 设置为 `Integer.MIN_VALUE` 的方式,比第二种功能实现更简单且执行效率更高。
TiDB 同时支持以上两种方式,但更推荐使用第一种将 `FetchSize` 设置为 `Integer.MIN_VALUE` 的方式,比第二种功能实现更简单且执行效率更高。

对于第二种方式,TiDB 会先将所有数据加载到 TiDB 节点上,然后根据 `FetchSize` 依次返回给客户端。因此,通常会比第一种方式使用更多内存。如果将 [`tidb_enable_tmp_storage_on_oom`](/system-variables.md#tidb_enable_tmp_storage_on_oom) 设置为 `ON`,可能会触发落盘临时将结果写入硬盘。

如果系统变量 [`tidb_enable_lazy_cursor_fetch`](/system-variables.md#tidb_enable_lazy_cursor_fetch-从-v830-版本开始引入) 设置为 `ON`,TiDB 将尝试仅在客户端请求数据时读取部分数据,以使用更少的内存。更多信息和使用限制,参见系统变量 [`tidb_enable_lazy_cursor_fetch`](/system-variables.md#tidb_enable_lazy_cursor_fetch-从-v830-版本开始引入) 的详细描述。

### MySQL JDBC 参数

Expand Down
21 changes: 21 additions & 0 deletions system-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -1926,6 +1926,27 @@ mysql> SELECT job_info FROM mysql.analyze_jobs ORDER BY end_time DESC LIMIT 1;
- 可选值:`OFF`,`ON`
- 这个变量用于控制是否支持对分区表创建 `Global index`。`Global index` 当前正处于开发阶段,**不推荐修改该变量值**。

### `tidb_enable_lazy_cursor_fetch` <span class="version-mark">从 v8.3.0 版本开始引入</span>

> **警告:**
>
> 该变量控制的功能为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。

- 作用域:GLOBAL
- 是否持久化到集群:是
- 是否受 Hint [SET_VAR](/optimizer-hints.md#set_varvar_namevar_value) 控制:否
- 类型:布尔型
- 默认值:`OFF`
YangKeao marked this conversation as resolved.
Show resolved Hide resolved
- 可选值:`OFF`,`ON`
- 这个变量用于控制 [Cursor Fetch](/develop/dev-guide-connection-parameters.md#使用-streamingresult-流式获取执行结果) 功能的行为。
- 当开启 Cursor Fetch 且该变量设置为 `OFF` 时,TiDB 会在语句开始执行时将所有数据读取完成并保存至 TiDB 内存,在后续客户端读取的过程中会依据客户端指定的 `FetchSize` 返回给客户端。如果结果集过大,可能会触发落盘临时将结果写入硬盘。
- 当开启 Cursor Fetch 且该变量设置为 `ON` 时,TiDB 不会一次把所有数据读取到 TiDB 节点,而是会随着客户端的读取不断将数据读到 TiDB 节点。
- 该变量控制的功能存在以下限制:
- 不支持处于显式事务中的语句。
- 当前仅支持包含且仅包含 `TableReader`、`IndexReader`、`IndexLookUp`、`Projection`、`Selection` 算子的执行计划。
- 对于使用 Lazy Cursor Fetch 的语句,执行信息将不会出现在 [statements summary](/statement-summary-tables.md) 和[慢查询日志](/identify-slow-queries.md)中。
- 对于暂不支持的场景,其行为与将变量设置为 `OFF` 时一致。

### `tidb_enable_non_prepared_plan_cache`

- 作用域:SESSION | GLOBAL
Expand Down