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/releases/release-8.5.7.md b/releases/release-8.5.7.md index 5f86a58129689..e614fde70882b 100644 --- a/releases/release-8.5.7.md +++ b/releases/release-8.5.7.md @@ -174,7 +174,7 @@ For TiDB clusters newly deployed in v8.5.6 (that is, v8.5.6 clusters that are no - Support nested parentheses in the `LEADING` optimizer hint to specify more complex join orders, such as `LEADING((a, b), (c, d))` [#63253](https://github.com/pingcap/tidb/issues/63253) @[guo-shaoge](https://github.com/guo-shaoge) - Improve join plan selection to avoid choosing inefficient index joins when the estimated probe rows are close to a full scan, improving query performance in some `HASHAGG` + join scenarios [#67610](https://github.com/pingcap/tidb/issues/67610) @[qw4990](https://github.com/qw4990) - Improve query performance for nested `OR` conditions by enabling more efficient `IndexMerge` plans and allowing redundant global filters to be removed so `LIMIT` can be pushed down [#65822](https://github.com/pingcap/tidb/issues/65822) @[time-and-fate](https://github.com/time-and-fate) - - Support the `FLUSH STATS_DELTA` statement to persist pending optimizer statistics deltas for all, database, or table scopes [#65668](https://github.com/pingcap/tidb/issues/65668) @[0xPoe](https://github.com/0xPoe) + - Support the [`FLUSH STATS_DELTA`](https://docs.pingcap.com/tidb/v8.5/sql-statement-flush-stats-delta) statement to persist pending optimizer statistics deltas for all, database, or table scopes [#65668](https://github.com/pingcap/tidb/issues/65668) @[0xPoe](https://github.com/0xPoe) - Improve query optimization by enabling the optimizer fix control for considering `IndexMerge` when alternative indexes exist by default, so TiDB can choose `IndexMerge` plans in more applicable queries [#26764](https://github.com/pingcap/tidb/issues/26764) @[time-and-fate](https://github.com/time-and-fate) - Support caching prepared and non-prepared queries that use `set_var` and `resource_group` hints to improve plan cache hit rates for hinted queries [#60920](https://github.com/pingcap/tidb/issues/60920) @[qw4990](https://github.com/qw4990) - Optimize `ORDER BY ... LIMIT` and `ORDER BY ... TOPN` queries that use `IndexMerge` by pushing `Limit` or `TopN` down to individual partial paths when possible, reducing unnecessary scans and sorting in some query plans [#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 0000000000000..b3a736f2fe365 --- /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 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. + +When you change data using DML statements (such as `INSERT`, `UPDATE`, and `DELETE`), TiDB records changes to the total row count and modified row count of each affected table, buffers these changes (called the statistics delta) in the memory of the TiDB node 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 depend on the persisted statistics metadata, `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 + +```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 the tables whose statistics delta you want 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 all tables in the specified database. + - `*.*`: flushes the statistics delta of all tables. +- **`CLUSTER`**: broadcasts the statement to all TiDB nodes in the cluster. Each TiDB node buffers the statistics delta of the DML statements that it executes. Without this option, TiDB only persists the delta buffered on the TiDB node you are connected to. + +Note the following behavior: + +- TiDB deduplicates overlapping targets. For example, in `FLUSH STATS_DELTA *.*, test.t`, the `test.t` target is ignored because `*.*` already includes all tables. Similarly, in `FLUSH STATS_DELTA test.*, test.t`, the `test.t` target is ignored because `test.*` already includes all tables in the `test` 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) +``` + +TiDB has now persisted the row count changes of the table to the `mysql.stats_meta` system table. You can view persisted values using `SHOW STATS_META`. Note that `SHOW STATS_META` reads statistics from the memory of the TiDB node you are connected to. Because this TiDB node 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'; +``` + +``` ++---------+------------+----------------+---------------------+--------------+-----------+-------------------+ +| 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 node 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.