diff --git a/sql-plan-management.md b/sql-plan-management.md index 2c1d4fa039643..9b4f0bddd80ab 100644 --- a/sql-plan-management.md +++ b/sql-plan-management.md @@ -21,42 +21,46 @@ CREATE [GLOBAL | SESSION] BINDING FOR BindableStmt USING BindableStmt This statement binds SQL execution plans at the GLOBAL or SESSION level. Currently, supported bindable SQL statements (BindableStmt) in TiDB include `SELECT`, `DELETE`, `UPDATE`, and `INSERT` / `REPLACE` with `SELECT` subqueries. +> **Note:** +> +> Bindings have higher priority over manually added hints. Therefore, when you execute a statement containing a hint while a corresponding binding is present, the hint controlling the behavior of the optimizer does not take effect. However, other types of hints are still effective. + Specifically, two types of these statements cannot be bound to execution plans due to syntax conflicts. See the following examples: ```sql --- Type one: Statements that get the Cartesian product by using the `join` keyword and not specifying the associated columns with the `using` keyword. -create global binding for - select * from t t1 join t t2 -using - select * from t t1 join t t2; - --- Type two: `DELETE` statements that contain the `using` keyword. -create global binding for - delete from t1 using t1 join t2 on t1.a = t2.a -using - delete from t1 using t1 join t2 on t1.a = t2.a; +-- Type one: Statements that get the Cartesian product by using the `JOIN` keyword and not specifying the associated columns with the `USING` keyword. +CREATE GLOBAL BINDING for + SELECT * FROM t t1 JOIN t t2 +USING + SELECT * FROM t t1 JOIN t t2; + +-- Type two: `DELETE` statements that contain the `USING` keyword. +CREATE GLOBAL BINDING for + DELETE FROM t1 USING t1 JOIN t2 ON t1.a = t2.a +USING + DELETE FROM t1 USING t1 JOIN t2 ON t1.a = t2.a; ``` You can bypass syntax conflicts by using equivalent statements. For example, you can rewrite the above statements in the following ways: ```sql --- First rewrite of type one statements: Add a `using` clause for the `join` keyword. -create global binding for - select * from t t1 join t t2 using (a) +-- First rewrite of type one statements: Add a `USING` clause for the `JOIN` keyword. +CREATE GLOBAL BINDING for + SELECT * FROM t t1 JOIN t t2 USING (a) +USING + SELECT * FROM t t1 JOIN t t2 USING (a); + +-- Second rewrite of type one statements: Delete the `JOIN` keyword. +CREATE GLOBAL BINDING for + SELECT * FROM t t1, t t2 +USING + SELECT * FROM t t1, t t2; + +-- Rewrite of type two statements: Remove the `USING` keyword from the `delete` statement. +CREATE GLOBAL BINDING for + DELETE t1 FROM t1 JOIN t2 ON t1.a = t2.a using - select * from t t1 join t t2 using (a); - --- Second rewrite of type one statements: Delete the `join` keyword. -create global binding for - select * from t t1, t t2 -using - select * from t t1, t t2; - --- Rewrite of type two statements: Remove the `using` keyword from the `delete` statement. -create global binding for - delete t1 from t1 join t2 on t1.a = t2.a -using - delete t1 from t1 join t2 on t1.a = t2.a; + DELETE t1 FROM t1 JOIN t2 ON t1.a = t2.a; ``` > **Note:** @@ -67,16 +71,16 @@ Here are two examples: ```sql -- The hint takes effect in the following statement. -create global binding for - insert into t1 select * from t2 where a > 1 and b = 1 +CREATE GLOBAL BINDING for + INSERT INTO t1 SELECT * FROM t2 WHERE a > 1 AND b = 1 using - insert into t1 select /*+ use_index(@sel_1 t2, a) */ * from t2 where a > 1 and b = 1; + INSERT INTO t1 SELECT /*+ use_index(@sel_1 t2, a) */ * FROM t2 WHERE a > 1 AND b = 1; -- The hint cannot take effect in the following statement. -create global binding for - insert into t1 select * from t2 where a > 1 and b = 1 +CREATE GLOBAL BINDING for + INSERT INTO t1 SELECT * FROM t2 WHERE a > 1 AND b = 1 using - insert /*+ use_index(@sel_1 t2, a) */ into t1 select * from t2 where a > 1 and b = 1; + INSERT /*+ use_index(@sel_1 t2, a) */ INTO t1 SELECT * FROM t2 WHERE a > 1 AND b = 1; ``` If you do not specify the scope when creating an execution plan binding, the default scope is SESSION. The TiDB optimizer normalizes bound SQL statements and stores them in the system table. When processing SQL queries, if a normalized statement matches one of the bound SQL statements in the system table and the system variable `tidb_use_plan_baselines` is set to `on` (the default value is `on`), TiDB then uses the corresponding optimizer hint for this statement. If there are multiple matchable execution plans, the optimizer chooses the least costly one to bind. @@ -84,9 +88,9 @@ If you do not specify the scope when creating an execution plan binding, the def `Normalization` is a process that converts a constant in an SQL statement to a variable parameter and explicitly specifies the database for tables referenced in the query, with standardized processing on the spaces and line breaks in the SQL statement. See the following example: ```sql -select * from t where a > 1 +SELECT * FROM t WHERE a > 1 -- After normalization, the above statement is as follows: -select * from test . t where a > ? +SELECT * FROM test . t WHERE a > ? ``` > **Note:** @@ -96,15 +100,15 @@ select * from test . t where a > ? > For example: > > ```sql -> select * from t limit 10 -> select * from t limit 10, 20 -> select * from t where a in (1) -> select * from t where a in (1,2,3) +> SELECT * FROM t limit 10 +> SELECT * FROM t limit 10, 20 +> SELECT * FROM t WHERE a IN (1) +> SELECT * FROM t WHERE a IN (1,2,3) > -- After normalization, the above statements are as follows: -> select * from test . t limit ? -> select * from test . t limit ... -> select * from test . t where a in ( ? ) -> select * from test . t where a in ( ... ) +> SELECT * FROM test . t limit ? +> SELECT * FROM test . t limit ... +> SELECT * FROM test . t WHERE a IN ( ? ) +> SELECT * FROM test . t WHERE a IN ( ... ) > ``` > > When bindings are created, TiDB treats SQL statements that contain a single constant and SQL statements that contain multiple constants joined by commas differently. Therefore, you need to create bindings for the two SQL types separately. @@ -115,25 +119,25 @@ For example: ```sql -- Creates a GLOBAL binding and specifies using `sort merge join` in this binding. -create global binding for - select * from t1, t2 where t1.id = t2.id -using - select /*+ merge_join(t1, t2) */ * from t1, t2 where t1.id = t2.id; +CREATE GLOBAL BINDING for + SELECT * FROM t1, t2 WHERE t1.id = t2.id +USING + SELECT /*+ merge_join(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id; -- The execution plan of this SQL statement uses the `sort merge join` specified in the GLOBAL binding. -explain select * from t1, t2 where t1.id = t2.id; +explain SELECT * FROM t1, t2 WHERE t1.id = t2.id; -- Creates another SESSION binding and specifies using `hash join` in this binding. -create binding for - select * from t1, t2 where t1.id = t2.id -using - select /*+ hash_join(t1, t2) */ * from t1, t2 where t1.id = t2.id; +CREATE BINDING for + SELECT * FROM t1, t2 WHERE t1.id = t2.id +USING + SELECT /*+ hash_join(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id; -- In the execution plan of this statement, `hash join` specified in the SESSION binding is used, instead of `sort merge join` specified in the GLOBAL binding. -explain select * from t1, t2 where t1.id = t2.id; +explain SELECT * FROM t1, t2 WHERE t1.id = t2.id; ``` -When the first `select` statement is being executed, the optimizer adds the `sm_join(t1, t2)` hint to the statement through the binding in the GLOBAL scope. The top node of the execution plan in the `explain` result is MergeJoin. When the second `select` statement is being executed, the optimizer uses the binding in the SESSION scope instead of the binding in the GLOBAL scope and adds the `hash_join(t1, t2)` hint to the statement. The top node of the execution plan in the `explain` result is HashJoin. +When the first `SELECT` statement is being executed, the optimizer adds the `sm_join(t1, t2)` hint to the statement through the binding in the GLOBAL scope. The top node of the execution plan in the `explain` result is MergeJoin. When the second `SELECT` statement is being executed, the optimizer uses the binding in the SESSION scope instead of the binding in the GLOBAL scope and adds the `hash_join(t1, t2)` hint to the statement. The top node of the execution plan in the `explain` result is HashJoin. Each standardized SQL statement can have only one binding created using `CREATE BINDING` at a time. When multiple bindings are created for the same standardized SQL statement, the last created binding is retained, and all previous bindings (created and evolved) are marked as deleted. But session bindings and global bindings can coexist and are not affected by this logic. @@ -141,13 +145,13 @@ In addition, when you create a binding, TiDB requires that the session is in a d The original SQL statement and the bound statement must have the same text after normalization and hint removal, or the binding will fail. Take the following examples: -- This binding can be created successfully because the texts before and after parameterization and hint removal are the same: `select * from test . t where a > ?` +- This binding can be created successfully because the texts before and after parameterization and hint removal are the same: `SELECT * FROM test . t WHERE a > ?` ```sql CREATE BINDING FOR SELECT * FROM t WHERE a > 1 USING SELECT * FROM t use index (idx) WHERE a > 2 ``` -- This binding will fail because the original SQL statement is processed as `select * from test . t where a > ?`, while the bound SQL statement is processed differently as `select * from test . t where b > ?`. +- This binding will fail because the original SQL statement is processed as `SELECT * FROM test . t WHERE a > ?`, while the bound SQL statement is processed differently as `SELECT * FROM test . t WHERE b > ?`. ```sql CREATE BINDING FOR SELECT * FROM t WHERE a > 1 USING SELECT * FROM t use index(idx) WHERE b > 2 @@ -173,10 +177,10 @@ The following example is based on the example in [create binding](#create-a-bind ```sql -- Drops the binding created in the SESSION scope. -drop session binding for select * from t1, t2 where t1.id = t2.id; +drop session binding for SELECT * FROM t1, t2 WHERE t1.id = t2.id; -- Views the SQL execution plan again. -explain select * from t1,t2 where t1.id = t2.id; +explain SELECT * FROM t1,t2 WHERE t1.id = t2.id; ``` In the example above, the dropped binding in the SESSION scope shields the corresponding binding in the GLOBAL scope. The optimizer does not add the `sm_join(t1, t2)` hint to the statement. The top node of the execution plan in the `explain` result is not fixed to MergeJoin by this hint. Instead, the top node is independently selected by the optimizer according to the cost estimation. @@ -185,7 +189,19 @@ In the example above, the dropped binding in the SESSION scope shields the corre > > Executing `DROP GLOBAL BINDING` drops the binding in the current tidb-server instance cache and changes the status of the corresponding row in the system table to 'deleted'. This statement does not directly delete the records in the system table, because other tidb-server instances need to read the 'deleted' status to drop the corresponding binding in their cache. For the records in these system tables with the status of 'deleted', at every 100 `bind-info-lease` (the default value is `3s`, and `300s` in total) interval, the background thread triggers an operation of reclaiming and clearing on the bindings of `update_time` before 10 `bind-info-lease` (to ensure that all tidb-server instances have read the 'deleted' status and updated the cache). -### View binding +## Change binding status + +{{< copyable "sql" >}} + +```sql +SET BINDING [ENABLED | DISABLED] FOR BindableStmt; +``` + +You can execute this statement to change the status of a binding. The default status is ENABLED. The effective scope is GLOBAL by default and cannot be modified. + +When executing this statement, you can only change the status of a binding from `Disabled` to `Enabled` or from `Enabled` to `Disabled`. If no binding is available for status changes, a warning message is returned, saying `There are no bindings can be set the status. Please check the SQL text`. Note that a binding in `Disabled` status is not used by any query. + +### View bindings {{< copyable "sql" >}} @@ -200,41 +216,98 @@ This statement outputs the execution plan bindings at the GLOBAL or SESSION leve | original_sql | Original SQL statement after parameterization | | bind_sql | Bound SQL statement with hints | | default_db | Default database | -| status | Status including Using, Deleted, Invalid, Rejected, and Pending verification| +| status | Status including Enabled (replacing the Using status from v6.0), Disabled, Deleted, Invalid, Rejected, and Pending verification| | create_time | Creating time | | update_time | Updating time | | charset | Character set | | collation | Ordering rule | | source | The way in which a binding is created, including `manual` (created by the `create [global] binding` SQL statement), `capture` (captured automatically by TiDB), and `evolve` (evolved automatically by TiDB) | -### Troubleshoot binding +### Troubleshoot a binding -{{< copyable "sql" >}} +You can use either of the following methods to troubleshoot a binding: -```sql -SELECT @@[SESSION.]last_plan_from_binding; -``` +- Use the system variable [`last_plan_from_binding`](/system-variables.md#last_plan_from_binding-new-in-v40) to show whether the execution plan used by the last executed statement is from the binding. -This statement uses the system variable [`last_plan_from_binding`](/system-variables.md#last_plan_from_binding-new-in-v40) to show whether the execution plan used by the last executed statement is from the binding. + {{< copyable "sql" >}} -In addition, when you use the `explain format = 'verbose'` statement to view the query plan of a SQL statement, if the SQL statement uses binding, the `explain` statement will return a warning. In this situation, you can check the warning message to learn which binding is used in the SQL statement. + ```sql + -- Create a global binding + CREATE GLOBAL BINDING for + SELECT * FROM t + USING + SELECT /*+ USE_INDEX(t, idx_a) */ * FROM t; + + SELECT * FROM t; + SELECT @@[SESSION.]last_plan_from_binding; + ``` -```sql --- Create a global binding. + ```sql + +--------------------------+ + | @@last_plan_from_binding | + +--------------------------+ + | 1 | + +--------------------------+ + 1 row in set (0.00 sec) + ``` -create global binding for - select * from t -using - select * from t; +- Use the `explain format = 'verbose'` statement to view the query plan of a SQL statement. If the SQL statement uses a binding, you can run `show warnings` to check which binding is used in the SQL statement. + + ```sql + -- Create a global binding + + CREATE GLOBAL BINDING for + SELECT * FROM t + USING + SELECT /*+ USE_INDEX(t, idx_a) */ * FROM t; + + -- Use explain format = 'verbose' to view the execution plan of a SQL statement + + explain format = 'verbose' SELECT * FROM t; + + -- Run `show warnings` to view the binding used in the query. + + show warnings; + ``` + + ```sql + +-------+------+--------------------------------------------------------------------------+ + | Level | Code | Message | + +-------+------+--------------------------------------------------------------------------+ + | Note | 1105 | Using the bindSQL: SELECT /*+ USE_INDEX(`t` `idx_a`)*/ * FROM `test`.`t` | + +-------+------+--------------------------------------------------------------------------+ + 1 row in set (0.01 sec) + + ``` + +### Cache bindings --- Use the `explain format = 'verbose'` statement to check the SQL execution plan. Check the warning message to view the binding used in the query. +Each TiDB instance has a least recently used (LRU) cache for bindings. The cache capacity is controlled by the system variable [`tidb_mem_quota_binding_cache`](/system-variables.md#tidb_mem_quota_binding_cache-new-in-v600). You can view bindings that are cached in the TiDB instance. -explain format = 'verbose' select * from t; -show warnings; +To view the cache status of bindings, run the `SHOW binding_cache status` statement. In this statement, the effective scope is GLOBAL by default and cannot be modified. This statement returns the number of available bindings in the cache, the total number of available bindings in the system, memory usage of all cached bindings, and the total memory for the cache. + +{{< copyable "sql" >}} + +```sql + +SHOW binding_cache status; +``` + +```sql ++-------------------+-------------------+--------------+--------------+ +| bindings_in_cache | bindings_in_table | memory_usage | memory_quota | ++-------------------+-------------------+--------------+--------------+ +| 1 | 1 | 159 Bytes | 64 MB | ++-------------------+-------------------+--------------+--------------+ +1 row in set (0.00 sec) ``` ## Baseline capturing +Used for [preventing regression of execution plans during an upgrade](#prevent-regression-of-execution-plans-during-an-upgrade), this feature captures queries that meet capturing conditions and creates bindings for these queries. + +### Enable capturing + To enable baseline capturing, set `tidb_capture_plan_baselines` to `on`. The default value is `off`. > **Note:** @@ -247,7 +320,12 @@ However, TiDB does not automatically capture bindings for the following types of - `EXPLAIN` and `EXPLAIN ANALYZE` statements. - SQL statements executed internally in TiDB, such as `SELECT` queries used for automatically loading statistical information. -- SQL statements that are bound to a manually created execution plan. +- Statements that contain `Enabled` or `Disabled` bindings. +- Statements that are filtered out by capturing conditions. + +> **Note:** +> +> Currently, a binding generates a group of hints to fix an execution plan generated by a query statement. In this way, for the same query, the execution plan does not change. For most OLTP queries, including queries using the same index or Join algorithm (such as HashJoin and IndexJoin), TiDB guarantees plan consistency before and after the binding. However, due to the limitations of hints, TiDB cannot guarantee plan consistency for some complex queries, such as Join of more than two tables, MPP queries, and complex OLAP queries. For `PREPARE` / `EXECUTE` statements and for queries executed with binary protocols, TiDB automatically captures bindings for the real query statements, not for the `PREPARE` / `EXECUTE` statements. @@ -255,6 +333,75 @@ For `PREPARE` / `EXECUTE` statements and for queries executed with binary protoc > > Because TiDB has some embedded SQL statements to ensure the correctness of some features, baseline capturing by default automatically shields these SQL statements. +### Filter out bindings + +This feature allows you to configure a blocklist to filter out queries whose bindings you do not want to capture. A blocklist has three dimensions, table name, frequency, and user name. + +#### Usage + +Insert filtering conditions into the system table `mysql.capture_plan_baselines_blacklist`. Then the filtering conditions take effect in the entire cluster immediately. + +```sql +-- Filter by table name + INSERT INTO mysql.capture_plan_baselines_blacklist(filter_type, filter_value) VALUES('table', 'test.t'); + +-- Filter by database name and table name through wildcards + INSERT INTO mysql.capture_plan_baselines_blacklist(filter_type, filter_value) VALUES('table', 'test.table_*'); + INSERT INTO mysql.capture_plan_baselines_blacklist(filter_type, filter_value) VALUES('table', 'db_*.table_*'); + +-- Filter by frequency + INSERT INTO mysql.capture_plan_baselines_blacklist(filter_type, filter_value) VALUES('frequency', '2'); + +-- Filter by user name + INSERT INTO mysql.capture_plan_baselines_blacklist(filter_type, filter_value) VALUES('user', 'user1'); +``` + +| **Dimension name** | **Description** | Remarks | +| :----------- | :----------------------------------------------------------- | ------------------------------------------------------------ | +| table | Filter by table name. Each filtering rule is in the `db.table` format. The supported filtering syntax includes [Plain table names](/table-filter.md#plain-table-names) and [Wildcards](/table-filter.md#wildcards). | Case insensitive. If a table name contains illegal characters, the log returns a warning message `[sql-bind] failed to load mysql.capture_plan_baselines_blacklist`. | +| frequency | Filter by frequency. SQL statements executed more than once are captured by default. You can set a high frequency to capture statements that are frequently executed. | Setting frequency to a value smaller than 1 is considered illegal, and the log returns a warning message `[sql-bind] frequency threshold is less than 1, ignore it`. If multiple frequency filter rules are inserted, the value with the highest frequency prevails. | +| user | Filter by user name. Statements executed by blocklisted users are not captured. | If multiple users execute the same statement and their user names are all in the blocklist, this statement is not captured. | + +> **Note:** +> +> - Modifying a blocklist requires the super privilege. +> +> - If a blocklist contains illegal filters, TiDB returns the warning message `[sql-bind] unknown capture filter type, ignore it` in the log. + +### Prevent regression of execution plans during an upgrade + + Before upgrading a TiDB cluster, you can use baseline capturing to prevent regression of execution plans by performing the following steps: + +1. Enable baseline capturing and keep it working for a period of time. + + > **Note:** + > + > Test data shows that long-term working of baseline capturing has a slight impact on the performance of the cluster load. Therefore, it is recommended to enable baseline capturing as long as possible so that important plans (appear twice or above) are captured. + +2. Upgrade the TiDB cluster. After the upgrade, TiDB uses those captured bindings to ensure execution plan consistency. + +3. After the upgrade, delete bindings as required. + + - Check the binding source by running the [`SHOW GLOBAL BINDINGS`](#view-bindings) statement. + + In the output, check the `Source` field to see whether a binding is captured (`capture`) or manually created (`manual`). + + - Determine whether to retain the captured bindings: + + ``` + -- View the plan with the binding enabled + SET @@SESSION.TIDB_USE_PLAN_BASELINES = true; + EXPLAIN FORMAT='VERBOSE' SELECT * FROM t1 WHERE ...; + + -- View the plan with the binding disabled + SET @@SESSION.TIDB_USE_PLAN_BASELINES = false; + EXPLAIN FORMAT='VERBOSE' SELECT * FROM t1 WHERE ...; + ``` + + - If the execution plan is consistent, you can delete the binding safely. + + - If the execution plan is inconsistent, you need to identify the cause, for example, by checking statistics. In this case, you need to retain the binding to ensure plan consistency. + ## Baseline evolution Baseline evolution is an important feature of SPM introduced in TiDB v4.0. @@ -270,7 +417,7 @@ Use the following statement to enable automatic binding evolution: {{< copyable "sql" >}} ```sql -set global tidb_evolve_plan_baselines = on; +SET GLOBAL tidb_evolve_plan_baselines = ON; ``` The default value of `tidb_evolve_plan_baselines` is `off`. @@ -287,7 +434,7 @@ Assume that table `t` is defined as follows: {{< copyable "sql" >}} ```sql -create table t(a int, b int, key(a), key(b)); +CREATE TABLE t(a INT, b INT, KEY(a), KEY(b)); ``` Perform the following query on table `t`: @@ -295,7 +442,7 @@ Perform the following query on table `t`: {{< copyable "sql" >}} ```sql -select * from t where a < 100 and b < 100; +SELECT * FROM t WHERE a < 100 AND b < 100; ``` In the table defined above, few rows meet the `a < 100` condition. But for some reason, the optimizer mistakenly selects the full table scan instead of the optimal execution plan that uses index `a`. You can first use the following statement to create a binding: @@ -303,7 +450,7 @@ In the table defined above, few rows meet the `a < 100` condition. But for some {{< copyable "sql" >}} ```sql -create global binding for select * from t where a < 100 and b < 100 using select * from t use index(a) where a < 100 and b < 100; +CREATE GLOBAL BINDING for SELECT * FROM t WHERE a < 100 AND b < 100 using SELECT * FROM t use index(a) WHERE a < 100 AND b < 100; ``` When the query above is executed again, the optimizer selects index `a` (influenced by the binding created above) to reduce the query time. @@ -349,11 +496,11 @@ During cluster upgrade, SQL Plan Management (SPM) might cause compatibility issu ```sql -- Check whether `tidb_evolve_plan_baselines` is disabled in the earlier version. - select @@global.tidb_evolve_plan_baselines; + SELECT @@global.tidb_evolve_plan_baselines; -- If `tidb_evolve_plan_baselines` is still enabled, disable it. - set global tidb_evolve_plan_baselines = off; + SET GLOBAL tidb_evolve_plan_baselines = OFF; ``` * Before you upgrade from v4.0 to the current version, you need to check whether the syntax of all queries corresponding to the available SQL bindings is correct in the new version. If any syntax errors exist, delete the corresponding SQL binding. To do that, perform the following steps. @@ -363,7 +510,7 @@ During cluster upgrade, SQL Plan Management (SPM) might cause compatibility issu ```sql -- Check the query corresponding to the available SQL binding in the version to be upgraded. - select bind_sql from mysql.bind_info where status = 'using'; + SELECT bind_sql FROM mysql.bind_info WHERE status = 'using'; -- Verify the result from the above SQL query in the test environment of the new version. diff --git a/system-variables.md b/system-variables.md index c9c5ef0a651d8..c9ea759ba89ec 100644 --- a/system-variables.md +++ b/system-variables.md @@ -1228,6 +1228,15 @@ For a system upgraded to v5.0 from an earlier version, if you have not modified - This variable is used to set the memory usage threshold of the local cache in the `Apply` operator. - The local cache in the `Apply` operator is used to speed up the computation of the `Apply` operator. You can set the variable to `0` to disable the `Apply` cache feature. +### tidb_mem_quota_binding_cache (New in v6.0.0) + +- Scope: GLOBAL +- Default value: `67108864` (64 MiB) +- Range: `[0, 2147483647]` +- Unit: Bytes +- This variable is used to set the threshold of the memory used for caching bindings. +- If a system creates or captures excessive bindings, resulting in overuse of memory space, TiDB returns a warning in the log. In this case, the cache cannot hold all available bindings or determine which bindings to store. For this reason, some queries might miss their bindings. To address this problem, you can increase the value of this variable, which increases the memory used for caching bindings. After modifying this parameter, you need to run `admin reload bindings` to reload bindings and validate the modification. + ### tidb_mem_quota_query - Scope: SESSION