From c65cf26bf753a2c44cb45927715b0b7133cd540c Mon Sep 17 00:00:00 2001 From: 0xPoe Date: Mon, 13 Jul 2026 15:20:10 +0200 Subject: [PATCH 1/3] statistics: add docs for the FLUSH STATS_DELTA statement --- TOC.md | 1 + .../sql-statement-flush-stats-delta.md | 111 ++++++++++++++++++ sql-statements/sql-statement-overview.md | 1 + statistics.md | 2 +- 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 sql-statements/sql-statement-flush-stats-delta.md diff --git a/TOC.md b/TOC.md index 1e5eb2d15b018..1c8327107598f 100644 --- a/TOC.md +++ b/TOC.md @@ -720,6 +720,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/sql-statements/sql-statement-flush-stats-delta.md b/sql-statements/sql-statement-flush-stats-delta.md new file mode 100644 index 0000000000000..9340c7ebfceac --- /dev/null +++ b/sql-statements/sql-statement-flush-stats-delta.md @@ -0,0 +1,111 @@ +--- +title: FLUSH STATS_DELTA +summary: An overview of the usage of FLUSH STATS_DELTA for the TiDB database. +--- + +# FLUSH STATS_DELTA + +`FLUSH STATS_DELTA` persists the pending statistics delta buffered in TiDB memory to the [`mysql.stats_meta`](/mysql-schema/mysql-schema.md#statistics-system-tables) system table immediately. This statement is supported starting from v8.5.7 and v9.0.0. + +When you change data using DML statements (such as `INSERT`, `UPDATE`, and `DELETE`), TiDB records the changes to the total number of rows and the number of modified rows for each table, buffers these changes (called the statistics delta) in the memory of the TiDB instance that executes the statements, and persists them to the `mysql.stats_meta` system table every 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease) (60 seconds by default). For more information, see [Automatic update](/statistics.md#automatic-update). + +Because the [health state of tables](/sql-statements/sql-statement-show-stats-healthy.md), the output of [`SHOW STATS_META`](/sql-statements/sql-statement-show-stats-meta.md), and the scheduling of automatic statistics collection are based on the persisted values, `FLUSH STATS_DELTA` is useful when you need the persisted statistics metadata to reflect recent data changes immediately, for example, in testing scenarios that verify optimizer behavior. You do not need to execute this statement before [`ANALYZE TABLE`](/sql-statements/sql-statement-analyze-table.md), because TiDB automatically flushes the pending statistics delta of a table before collecting statistics on it. + +## Synopsis + +```ebnf+diagram +FlushStatsDeltaStmt ::= + 'FLUSH' 'STATS_DELTA' FlushTargetList ClusterOption? + +FlushTargetList ::= + FlushTarget (',' FlushTarget)* + +FlushTarget ::= + TableName + | SchemaWildcard + | GlobalWildcard + +TableName ::= + Identifier ('.' Identifier)? + +SchemaWildcard ::= + Identifier '.' '*' + +GlobalWildcard ::= + '*' '.' '*' + +ClusterOption ::= + 'CLUSTER' +``` + +## Options + +- **Targets (`FlushTargetList`)**: specifies which tables to flush. At least one target is required. + - `table_name`: flushes the statistics delta of a table in the current database. If no database is selected, TiDB returns the `No database selected` error. + - `db_name.table_name`: flushes the statistics delta of a table in the specified database. + - `db_name.*`: flushes the statistics delta of every table in the specified database. + - `*.*`: flushes the statistics delta of every table. +- **`CLUSTER`**: broadcasts the statement to every TiDB instance in the cluster. Each TiDB instance buffers the statistics delta of the DML statements that it executes, so without this option, only the delta buffered on the TiDB instance that you are connected to is persisted. + +Note the following behavior: + +- Overlapping targets are deduplicated: `*.*` covers all other targets, and `db_name.*` covers tables in that database. +- For a partitioned table, TiDB persists the statistics delta of the table and all its partitions. +- If a specified database or table does not exist, TiDB returns a warning and skips that target. + +## Examples + +Persist the statistics delta of a single table immediately after data changes: + +```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) +``` + +The changes to the row counts of the table are now persisted to the `mysql.stats_meta` system table. You can view them using `SHOW STATS_META`. Note that `SHOW STATS_META` reads statistics from the memory of the TiDB instance that you are connected to, which loads the persisted values within [`stats-lease`](/tidb-configuration-file.md#stats-lease) (`3s` by default), so the flushed values might appear in its output after a short delay: + +```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) +``` + +Persist the statistics delta of a table in the current database and every table in the `sales` database: + +```sql +FLUSH STATS_DELTA t, sales.*; +``` + +Persist the statistics delta of all tables buffered on every TiDB instance in the cluster: + +```sql +FLUSH STATS_DELTA *.* CLUSTER; +``` + +## Privileges + +To execute `FLUSH STATS_DELTA`, you must have the `SELECT` privilege on the target objects: the target table for `table_name` or `db_name.table_name` targets, the target database for `db_name.*` targets, and the global `SELECT` privilege for `*.*` targets. Unlike other `FLUSH` statements, `FLUSH STATS_DELTA` does not require the `RELOAD` privilege. + +## MySQL compatibility + +`FLUSH STATS_DELTA` is a TiDB extension to MySQL syntax. + +## See also + +- [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) diff --git a/sql-statements/sql-statement-overview.md b/sql-statements/sql-statement-overview.md index a0395ad22e657..e60dc29d34660 100644 --- a/sql-statements/sql-statement-overview.md +++ b/sql-statements/sql-statement-overview.md @@ -323,6 +323,7 @@ TiDB uses SQL statements that aim to follow ISO/IEC SQL standards, with extensio | [`DROP BINDING`](/sql-statements/sql-statement-drop-binding.md) | Drops an execution plan binding from a SQL statement. | | [`DROP STATS`](/sql-statements/sql-statement-drop-stats.md) | Drops statistics from a table. | | [`EXPLAIN ANALYZE`](/sql-statements/sql-statement-explain-analyze.md) | Works similar to `EXPLAIN`, with the major difference that it will execute the statement. | +| [`FLUSH STATS_DELTA`](/sql-statements/sql-statement-flush-stats-delta.md) | Persists the pending statistics delta in TiDB memory to the system table immediately. | | [`LOAD STATS`](/sql-statements/sql-statement-load-stats.md) | Loads statistics into TiDB. | | [`REFRESH STATS`](/sql-statements/sql-statement-refresh-stats.md) | Reloads persisted statistics into memory for specific tables or the entire cluster. | | [`SHOW ANALYZE STATUS`](/sql-statements/sql-statement-show-analyze-status.md) | Shows statistics collection tasks. | diff --git a/statistics.md b/statistics.md index efb7de1a65db8..de08977167574 100644 --- a/statistics.md +++ b/statistics.md @@ -18,7 +18,7 @@ For the [`INSERT`](/sql-statements/sql-statement-insert.md), [`DELETE`](/sql-sta -TiDB persists the update information regularly and the update cycle is 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease). The default value of `stats-lease` is `3s`. If you specify the value as `0`, TiDB stops updating statistics automatically. +TiDB persists the update information regularly and the update cycle is 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease). The default value of `stats-lease` is `3s`. If you specify the value as `0`, TiDB stops updating statistics automatically. Starting from v8.5.7 and v9.0.0, you can use the [`FLUSH STATS_DELTA`](/sql-statements/sql-statement-flush-stats-delta.md) statement to persist the update information immediately. From 7ca8f426ec7a89897046427ec7f4433f0d10070d Mon Sep 17 00:00:00 2001 From: 0xPoe Date: Mon, 13 Jul 2026 15:40:16 +0200 Subject: [PATCH 2/3] address review comments: use active voice and second person --- sql-statements/sql-statement-flush-stats-delta.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sql-statements/sql-statement-flush-stats-delta.md b/sql-statements/sql-statement-flush-stats-delta.md index 9340c7ebfceac..0a36420b5adb9 100644 --- a/sql-statements/sql-statement-flush-stats-delta.md +++ b/sql-statements/sql-statement-flush-stats-delta.md @@ -5,11 +5,11 @@ summary: An overview of the usage of FLUSH STATS_DELTA for the TiDB database. # FLUSH STATS_DELTA -`FLUSH STATS_DELTA` persists the pending statistics delta buffered in TiDB memory to the [`mysql.stats_meta`](/mysql-schema/mysql-schema.md#statistics-system-tables) system table immediately. This statement is supported starting from v8.5.7 and v9.0.0. +`FLUSH STATS_DELTA` persists the pending statistics delta buffered in TiDB memory to the [`mysql.stats_meta`](/mysql-schema/mysql-schema.md#statistics-system-tables) system table immediately. TiDB supports this statement starting from v8.5.7 and v9.0.0. When you change data using DML statements (such as `INSERT`, `UPDATE`, and `DELETE`), TiDB records the changes to the total number of rows and the number of modified rows for each table, buffers these changes (called the statistics delta) in the memory of the TiDB instance that executes the statements, and persists them to the `mysql.stats_meta` system table every 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease) (60 seconds by default). For more information, see [Automatic update](/statistics.md#automatic-update). -Because the [health state of tables](/sql-statements/sql-statement-show-stats-healthy.md), the output of [`SHOW STATS_META`](/sql-statements/sql-statement-show-stats-meta.md), and the scheduling of automatic statistics collection are based on the persisted values, `FLUSH STATS_DELTA` is useful when you need the persisted statistics metadata to reflect recent data changes immediately, for example, in testing scenarios that verify optimizer behavior. You do not need to execute this statement before [`ANALYZE TABLE`](/sql-statements/sql-statement-analyze-table.md), because TiDB automatically flushes the pending statistics delta of a table before collecting statistics on it. +Because the [health state of tables](/sql-statements/sql-statement-show-stats-healthy.md), the output of [`SHOW STATS_META`](/sql-statements/sql-statement-show-stats-meta.md), and the scheduling of automatic statistics collection depend on the persisted values, `FLUSH STATS_DELTA` is useful when you need the persisted statistics metadata to reflect recent data changes immediately, such as in testing scenarios that verify optimizer behavior. You do not need to execute this statement before [`ANALYZE TABLE`](/sql-statements/sql-statement-analyze-table.md), because TiDB automatically flushes the pending statistics delta of a table before collecting statistics on it. ## Synopsis @@ -40,16 +40,16 @@ ClusterOption ::= ## Options -- **Targets (`FlushTargetList`)**: specifies which tables to flush. At least one target is required. - - `table_name`: flushes the statistics delta of a table in the current database. If no database is selected, TiDB returns the `No database selected` error. +- **Targets (`FlushTargetList`)**: specifies which tables to flush. You must specify at least one target. + - `table_name`: flushes the statistics delta of a table in the current database. If you do not select a database, TiDB returns the `No database selected` error. - `db_name.table_name`: flushes the statistics delta of a table in the specified database. - `db_name.*`: flushes the statistics delta of every table in the specified database. - `*.*`: flushes the statistics delta of every table. -- **`CLUSTER`**: broadcasts the statement to every TiDB instance in the cluster. Each TiDB instance buffers the statistics delta of the DML statements that it executes, so without this option, only the delta buffered on the TiDB instance that you are connected to is persisted. +- **`CLUSTER`**: broadcasts the statement to every TiDB instance in the cluster. Each TiDB instance buffers the statistics delta of the DML statements that it executes. Without this option, TiDB persists only the delta buffered on the instance you are connected to. Note the following behavior: -- Overlapping targets are deduplicated: `*.*` covers all other targets, and `db_name.*` covers tables in that database. +- TiDB deduplicates overlapping targets: `*.*` covers all other targets, and `db_name.*` covers tables in that database. - For a partitioned table, TiDB persists the statistics delta of the table and all its partitions. - If a specified database or table does not exist, TiDB returns a warning and skips that target. @@ -68,7 +68,7 @@ FLUSH STATS_DELTA t; Query OK, 0 rows affected (0.01 sec) ``` -The changes to the row counts of the table are now persisted to the `mysql.stats_meta` system table. You can view them using `SHOW STATS_META`. Note that `SHOW STATS_META` reads statistics from the memory of the TiDB instance that you are connected to, which loads the persisted values within [`stats-lease`](/tidb-configuration-file.md#stats-lease) (`3s` by default), so the flushed values might appear in its output after a short delay: +TiDB has now persisted the row count changes of the table to the `mysql.stats_meta` system table. You can view them using `SHOW STATS_META`. Note that `SHOW STATS_META` reads statistics from the memory of the TiDB instance you are connected to. Because this instance loads the persisted values within [`stats-lease`](/tidb-configuration-file.md#stats-lease) (`3s` by default), the flushed values might appear in the output after a short delay: ```sql SHOW STATS_META WHERE table_name = 't'; From 9be219aceb78805247ec1e20529f0a67e654bc73 Mon Sep 17 00:00:00 2001 From: Grace Cai Date: Wed, 15 Jul 2026 11:26:25 +0800 Subject: [PATCH 3/3] move the version support info to the title --- sql-statements/sql-statement-flush-stats-delta.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql-statements/sql-statement-flush-stats-delta.md b/sql-statements/sql-statement-flush-stats-delta.md index 0a36420b5adb9..5dfafada97f49 100644 --- a/sql-statements/sql-statement-flush-stats-delta.md +++ b/sql-statements/sql-statement-flush-stats-delta.md @@ -3,9 +3,9 @@ title: FLUSH STATS_DELTA summary: An overview of the usage of FLUSH STATS_DELTA for the TiDB database. --- -# FLUSH STATS_DELTA +# FLUSH STATS_DELTA New in v8.5.7 and v9.0.0 -`FLUSH STATS_DELTA` persists the pending statistics delta buffered in TiDB memory to the [`mysql.stats_meta`](/mysql-schema/mysql-schema.md#statistics-system-tables) system table immediately. TiDB supports this statement starting from v8.5.7 and v9.0.0. +`FLUSH STATS_DELTA` persists the pending statistics delta buffered in TiDB memory to the [`mysql.stats_meta`](/mysql-schema/mysql-schema.md#statistics-system-tables) system table immediately. When you change data using DML statements (such as `INSERT`, `UPDATE`, and `DELETE`), TiDB records the changes to the total number of rows and the number of modified rows for each table, buffers these changes (called the statistics delta) in the memory of the TiDB instance that executes the statements, and persists them to the `mysql.stats_meta` system table every 20 * [`stats-lease`](/tidb-configuration-file.md#stats-lease) (60 seconds by default). For more information, see [Automatic update](/statistics.md#automatic-update).