Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@
- [`FLASHBACK DATABASE`](/sql-statements/sql-statement-flashback-database.md)
- [`FLASHBACK TABLE`](/sql-statements/sql-statement-flashback-table.md)
- [`FLUSH PRIVILEGES`](/sql-statements/sql-statement-flush-privileges.md)
- [`FLUSH STATS_DELTA`](/sql-statements/sql-statement-flush-stats-delta.md)
- [`FLUSH STATUS`](/sql-statements/sql-statement-flush-status.md)
- [`FLUSH TABLES`](/sql-statements/sql-statement-flush-tables.md)
- [`GRANT <privileges>`](/sql-statements/sql-statement-grant-privileges.md)
Expand Down
2 changes: 1 addition & 1 deletion releases/release-8.5.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ TiDB 版本:8.5.7
- 支持在 `LEADING` optimizer hint 中使用嵌套括号来指定更复杂的连接顺序,例如 `LEADING((a, b), (c, d))` [#63253](https://github.com/pingcap/tidb/issues/63253) @[guo-shaoge](https://github.com/guo-shaoge)
- 改进 Join 执行计划选择,避免在估算 probe 行数接近全表扫描时选择低效的 index join,从而提升某些 `HASHAGG` + join 场景下的查询性能 [#67610](https://github.com/pingcap/tidb/issues/67610) @[qw4990](https://github.com/qw4990)
- 提升嵌套 `OR` 条件查询的性能,通过启用更高效的 `IndexMerge` 计划,并允许移除冗余全局过滤条件以便下推 `LIMIT` [#65822](https://github.com/pingcap/tidb/issues/65822) @[time-and-fate](https://github.com/time-and-fate)
- 支持 `FLUSH STATS_DELTA` 语句,用于持久化全部、数据库级或表级范围内待写入的优化器统计信息增量 [#65668](https://github.com/pingcap/tidb/issues/65668) @[0xPoe](https://github.com/0xPoe)
- 支持 [`FLUSH STATS_DELTA`](https://docs.pingcap.com/zh/tidb/v8.5/sql-statement-flush-stats-delta) 语句,用于持久化全部、数据库级或表级范围内待写入的优化器统计信息 delta [#65668](https://github.com/pingcap/tidb/issues/65668) @[0xPoe](https://github.com/0xPoe)
- 改进查询优化,默认启用用于在存在备选索引时考虑 `IndexMerge` 的优化器修复控制项,使 TiDB 能在更多适用查询中选择 `IndexMerge` 计划 [#26764](https://github.com/pingcap/tidb/issues/26764) @[time-and-fate](https://github.com/time-and-fate)
- 支持缓存使用 `set_var``resource_group` Hint 的预处理与非预处理查询,以提升带 Hint 查询的 plan cache 命中率 [#60920](https://github.com/pingcap/tidb/issues/60920) @[qw4990](https://github.com/qw4990)
- 优化使用 `IndexMerge``ORDER BY ... LIMIT``ORDER BY ... TOPN` 查询,在可能的情况下将 `Limit``TopN` 下推到各个 partial path,从而减少某些查询计划中不必要的扫描和排序 [#68773](https://github.com/pingcap/tidb/issues/68773) @[time-and-fate](https://github.com/time-and-fate)
Expand Down
117 changes: 117 additions & 0 deletions sql-statements/sql-statement-flush-stats-delta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
title: FLUSH STATS_DELTA
summary: TiDB 数据库中 FLUSH STATS_DELTA 的使用概况。
---

# FLUSH STATS_DELTA <span class="version-mark">从 v8.5.7 和 v9.0.0 开始引入</span>

通过 `FLUSH STATS_DELTA`,你可以将 TiDB 内存中缓存的待持久化的统计信息 delta 立即持久化到 [`mysql.stats_meta`](/mysql-schema/mysql-schema.md#统计信息相关系统表) 系统表中。

当执行 `INSERT`、`UPDATE`、`DELETE` 等 DML 语句修改数据时,TiDB 会记录每张受影响的表中总行数和修改行数的变化,并将这些变化(即统计信息 delta)缓存在执行这些语句的 TiDB 节点的内存中。默认情况下,TiDB 每隔 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease)(默认 60 秒)会将这些 delta 持久化到 `mysql.stats_meta` 系统表中。详情参考[自动更新](/statistics.md#自动更新)。

由于[表的统计信息健康度](/sql-statements/sql-statement-show-stats-healthy.md)、[`SHOW STATS_META`](/sql-statements/sql-statement-show-stats-meta.md) 的输出,以及统计信息自动收集的调度都依赖于已持久化的统计信息元数据,当你希望已持久化的统计信息元数据能立即反映最近的数据变更时(例如,在验证优化器行为的测试场景中),`FLUSH STATS_DELTA` 就会很有用。在你执行 [`ANALYZE TABLE`](/sql-statements/sql-statement-analyze-table.md) 时,无需提前执行 `FLUSH STATS_DELTA`,因为 TiDB 会在收集某张表的统计信息之前,自动刷新该表待持久化的统计信息 delta。

## 语法概要

```ebnf+diagram
FlushStatsDeltaStmt ::=
'FLUSH' 'STATS_DELTA' FlushTargetList ClusterOption?

FlushTargetList ::=
FlushTarget (',' FlushTarget)*

FlushTarget ::=
TableName
| SchemaWildcard
| GlobalWildcard

TableName ::=
Identifier ('.' Identifier)?

SchemaWildcard ::=
Identifier '.' '*'

GlobalWildcard ::=
'*' '.' '*'

ClusterOption ::=
'CLUSTER'
```

## 选项

- **Targets (`FlushTargetList`)**:指定要刷新统计信息 delta 的表。必须至少指定一个目标。
- `table_name`:刷新当前数据库中指定表的统计信息 delta。如果你当前未选择数据库,TiDB 会返回 `No database selected` 错误。
- `db_name.table_name`:刷新指定数据库中指定表的统计信息 delta。
- `db_name.*`:刷新指定数据库中所有表的统计信息 delta。
- `*.*`:刷新所有表的统计信息 delta。
- **`CLUSTER`**:在当前集群中的所有 TiDB 节点上执行该语句。每个 TiDB 节点都会缓存其自身执行的 DML 语句所产生的统计信息 delta。若不指定此选项,TiDB 只会持久化你当前连接的 TiDB 节点上缓存的统计信息 delta。

请注意以下行为:

- TiDB 会对要刷新的重复目标进行去重。例如,在 `FLUSH STATS_DELTA *.*, test.t` 中,`test.t` 会被忽略,因为 `*.*` 已涵盖所有表。类似地,在 `FLUSH STATS_DELTA test.*, test.t` 中,`test.t` 会被忽略,因为 `test.*` 已涵盖 `test` 数据库中的所有表。
- 对于分区表,TiDB 会持久化该表及其所有分区的统计信息 delta。
- 如果指定的数据库或表不存在,TiDB 会返回一条警告并跳过该目标。

## 示例

在数据变更后立即持久化单张表的统计信息 delta:

```sql
USE test;
CREATE TABLE t (a INT, b INT);
INSERT INTO t VALUES (1, 1), (2, 2), (3, 3);
FLUSH STATS_DELTA t;
```

```
Query OK, 0 rows affected (0.01 sec)
```

此时,TiDB 已将该表的行数变化持久化到 `mysql.stats_meta` 系统表。你可以使用 `SHOW STATS_META` 查看已持久化的值。注意,`SHOW STATS_META` 会从你当前连接的 TiDB 节点内存中读取统计信息。该 TiDB 节点会在 [`stats-lease`](/tidb-configuration-file.md#stats-lease)(默认 `3s`)周期内加载已持久化的值,因此刷新后的值可能会在短暂延迟后才显示在输出中:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

补充 stats-lease=0 的边界行为

当前表述暗示刷新后的值最多延迟一个 stats-lease 周期即可显示,但当 stats-lease=0 时不会自动加载更新的统计信息;用户执行 FLUSH STATS_DELTA 后仍可能看到旧值,需要显式执行 REFRESH STATS。(docs.pingcap.com)

As per path instructions,Markdown 文档中的可安全连续修复应提供精确替换文本。

建议直接替换
-注意,`SHOW STATS_META` 会从你当前连接的 TiDB 节点内存中读取统计信息。该 TiDB 节点会在 [`stats-lease`](/tidb-configuration-file.md#stats-lease)(默认 `3s`)周期内加载已持久化的值,因此刷新后的值可能会在短暂延迟后才显示在输出中:
+注意,`SHOW STATS_META` 会从你当前连接的 TiDB 节点内存中读取统计信息。该 TiDB 节点会在 [`stats-lease`](/tidb-configuration-file.md#stats-lease)(默认 `3s`)周期内加载已持久化的值;当 `stats-lease` 设置为 `0` 时不会自动加载。此时,如需让内存中的统计信息反映刚持久化的值,请执行 [`REFRESH STATS`](/sql-statements/sql-statement-refresh-stats.md)。因此,刷新后的值可能会在短暂延迟后显示,或在 `stats-lease=0` 时不会自动显示:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
此时,TiDB 已将该表的行数变化持久化到 `mysql.stats_meta` 系统表。你可以使用 `SHOW STATS_META` 查看已持久化的值。注意,`SHOW STATS_META` 会从你当前连接的 TiDB 节点内存中读取统计信息。该 TiDB 节点会在 [`stats-lease`](/tidb-configuration-file.md#stats-lease)(默认 `3s`)周期内加载已持久化的值,因此刷新后的值可能会在短暂延迟后才显示在输出中
此时,TiDB 已将该表的行数变化持久化到 `mysql.stats_meta` 系统表。你可以使用 `SHOW STATS_META` 查看已持久化的值。注意,`SHOW STATS_META` 会从你当前连接的 TiDB 节点内存中读取统计信息。该 TiDB 节点会在 [`stats-lease`](/tidb-configuration-file.md#stats-lease)(默认 `3s`)周期内加载已持久化的值;当 `stats-lease` 设置为 `0` 时不会自动加载。此时,如需让内存中的统计信息反映刚持久化的值,请执行 [`REFRESH STATS`](/sql-statements/sql-statement-refresh-stats.md)。因此,刷新后的值可能会在短暂延迟后显示,或在 `stats-lease=0` 时不会自动显示

Source: Path instructions


```sql
SHOW STATS_META WHERE table_name = 't';
```

```
+---------+------------+----------------+---------------------+--------------+-----------+-------------------+
| Db_name | Table_name | Partition_name | Update_time | Modify_count | Row_count | Last_analyze_time |
+---------+------------+----------------+---------------------+--------------+-----------+-------------------+
| test | t | | 2026-07-13 15:30:00 | 3 | 3 | NULL |
+---------+------------+----------------+---------------------+--------------+-----------+-------------------+
1 row in set (0.01 sec)
```

持久化当前数据库中某张表以及 `sales` 数据库中所有表的统计信息 delta:

```sql
FLUSH STATS_DELTA t, sales.*;
```

持久化集群中每个 TiDB 节点上缓存的所有表的统计信息 delta:

```sql
FLUSH STATS_DELTA *.* CLUSTER;
```

## 权限

执行 `FLUSH STATS_DELTA` 时,需要对操作对象拥有 `SELECT` 权限:

- 对于 `table_name` 或 `db_name.table_name`,你需要具有目标表的 `SELECT` 权限;
- 对于 `db_name.*`,你需要具有目标数据库的 `SELECT` 权限;
- 对于 `*.*`,你需要具有全局 `SELECT` 权限。

与其他 `FLUSH` 语句不同,`FLUSH STATS_DELTA` 不需要 `RELOAD` 权限。

## MySQL 兼容性

`FLUSH STATS_DELTA` 是 TiDB 对 MySQL 语法的扩展。

## 另请参阅

- [常规统计信息](/statistics.md)
- [`SHOW STATS_META`](/sql-statements/sql-statement-show-stats-meta.md)
- [`ANALYZE TABLE`](/sql-statements/sql-statement-analyze-table.md)
- [`REFRESH STATS`](/sql-statements/sql-statement-refresh-stats.md)
1 change: 1 addition & 0 deletions sql-statements/sql-statement-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ TiDB 使用的 SQL 语句旨在遵循 ISO/IEC SQL 标准,并在必要时对 My
| [`DROP BINDING`](/sql-statements/sql-statement-drop-binding.md) | 删除 SQL 语句的执行计划绑定。 |
| [`DROP STATS`](/sql-statements/sql-statement-drop-stats.md) | 删除表的统计信息。 |
| [`EXPLAIN ANALYZE`](/sql-statements/sql-statement-explain-analyze.md) | 工作方式类似于 `EXPLAIN`,但主要区别在于 `EXPLAIN ANALYZE` 会执行语句。 |
| [`FLUSH STATS_DELTA`](/sql-statements/sql-statement-flush-stats-delta.md) | 立即将 TiDB 内存中待持久化的统计信息 delta 持久化到系统表中。 |
| [`LOAD STATS`](/sql-statements/sql-statement-load-stats.md) | 将统计信息加载到 TiDB 中。 |
| [`REFRESH STATS`](/sql-statements/sql-statement-refresh-stats.md) | 将持久化的统计信息重新加载到内存中,适用于特定表或整个集群。 |
| [`SHOW ANALYZE STATUS`](/sql-statements/sql-statement-show-analyze-status.md) | 显示统计信息收集任务。 |
Expand Down
2 changes: 1 addition & 1 deletion statistics.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ TiDB 使用统计信息作为优化器的输入,用于估算 SQL 语句的执

对于 [`INSERT`](/sql-statements/sql-statement-insert.md)、[`DELETE`](/sql-statements/sql-statement-delete.md) 或 [`UPDATE`](/sql-statements/sql-statement-update.md) 语句,TiDB 会自动更新统计信息中表的总行数和修改的行数。

TiDB 会定期持久化更新的统计信息,更新周期为 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease)。`stats-lease` 配置项的默认值为 `3s`,如果将其指定为 `0`,TiDB 将停止自动更新统计信息。
TiDB 会定期持久化更新的统计信息,更新周期为 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease)。`stats-lease` 配置项的默认值为 `3s`,如果将其指定为 `0`,TiDB 将停止自动更新统计信息。从 v8.5.7 和 v9.0.0 开始,你可以使用 [`FLUSH STATS_DELTA`](/sql-statements/sql-statement-flush-stats-delta.md) 语句立即持久化更新信息。

TiDB 根据表的变更次数自动调度 [`ANALYZE`](/sql-statements/sql-statement-analyze-table.md) 来收集这些表的统计信息。统计信息的自动更新由下表中的系统变量控制。

Expand Down
Loading