diff --git a/TOC.md b/TOC.md index ae5aaf703016..b683c34291ec 100644 --- a/TOC.md +++ b/TOC.md @@ -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 `](/sql-statements/sql-statement-grant-privileges.md) diff --git a/releases/release-8.5.7.md b/releases/release-8.5.7.md index 1b1c96290b5f..1d0007b376a4 100644 --- a/releases/release-8.5.7.md +++ b/releases/release-8.5.7.md @@ -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/tidb/v8.5/sql-statement-flush-stats-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) diff --git a/sql-statements/sql-statement-flush-stats-delta.md b/sql-statements/sql-statement-flush-stats-delta.md new file mode 100644 index 000000000000..62511069f1af --- /dev/null +++ b/sql-statements/sql-statement-flush-stats-delta.md @@ -0,0 +1,111 @@ +--- +title: FLUSH STATS_DELTA +summary: TiDB 数据库中 FLUSH STATS_DELTA 用法概述。 +--- + +# FLUSH STATS_DELTA 于 v8.5.7 和 v9.0.0 新增 + +`FLUSH STATS_DELTA` 会立即将 TiDB 内存中缓冲的待持久化统计信息 delta 持久化到 [`mysql.stats_meta`](/mysql-schema/mysql-schema.md#statistics-system-tables) 系统表中。 + +当你使用 DML 语句(例如 `INSERT`、`UPDATE` 和 `DELETE`)修改数据时,TiDB 会记录每个受影响表的总行数和已修改行数的变化,将这些变化(称为 statistics delta)缓存在执行这些语句的 TiDB 节点内存中,并每隔 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease)(默认 60 秒)将其持久化到 `mysql.stats_meta` 系统表中。更多信息,参见[自动修改](/statistics.md#automatic-update)。 + +由于[表的健康状态](/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) 之前执行此语句,因为 TiDB 会在收集某个表的统计信息之前,自动刷新该表待持久化的 statistics 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`)内加载已持久化的值,因此刷新后的值可能会在短暂延迟后出现在输出中: + +```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](/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) \ No newline at end of file diff --git a/sql-statements/sql-statement-overview.md b/sql-statements/sql-statement-overview.md index a252ae4e1701..a1045345e163 100644 --- a/sql-statements/sql-statement-overview.md +++ b/sql-statements/sql-statement-overview.md @@ -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) | 显示统计信息收集任务。 | diff --git a/statistics.md b/statistics.md index 7b4653779b67..3274b77d6419 100644 --- a/statistics.md +++ b/statistics.md @@ -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) 来收集这些表的统计信息。统计信息的自动更新由下表中的系统变量控制。