diff --git a/sql-plan-management.md b/sql-plan-management.md index b62b92dca197..7dc2cdcf5d20 100644 --- a/sql-plan-management.md +++ b/sql-plan-management.md @@ -223,27 +223,27 @@ CREATE BINDING FOR SELECT * FROM t WHERE a > 1 USING SELECT * FROM t use index(i #### 根据历史执行计划创建绑定 -如需将 SQL 语句的执行计划固定为之前使用过的执行计划,可以使用 `plan_digest` 为该 SQL 语句绑定一个历史的执行计划。相比于使用 SQL 创建绑定的方式,此方式更加简便。 +如需将 SQL 语句的执行计划固定为之前使用过的执行计划,可以使用 Plan Digest 为该 SQL 语句绑定一个历史的执行计划。相比于使用 SQL 创建绑定的方式,此方式更加简便,并且支持一次为多个语句绑定执行计划。详细说明和更多示例参见 [`CREATE [GLOBAL|SESSION] BINDING`](/sql-statements/sql-statement-create-binding.md)。 以下为根据历史执行计划创建绑定的注意事项: - 该功能是根据历史的执行计划生成 hint 而实现的绑定,历史的执行计划来源是 [Statement Summary Tables](/statement-summary-tables.md),因此在使用此功能之前需开启系统变量 [`tidb_enable_stmt_summary`](/system-variables.md#tidb_enable_stmt_summary-从-v304-版本开始引入)。 - 对于包含子查询的查询、访问 TiFlash 的查询、3 张表或更多表进行 Join 的查询,自动生成的 hint 不够完备,可能导致无法完全固定住计划,对于这类情况在创建时会产生告警。 -- 原执行计划对应 SQL 语句中的 hint 也会被应用在创建的绑定中,如执行 `SELECT /*+ max_execution_time(1000) */ * FROM t` 后,使用其 `plan_digest` 创建的绑定中会带上 `max_execution_time(1000)`。 +- 原执行计划对应 SQL 语句中的 hint 也会被应用在创建的绑定中,如执行 `SELECT /*+ max_execution_time(1000) */ * FROM t` 后,使用其 Plan Digest 创建的绑定中会带上 `max_execution_time(1000)`。 -使用方式: +使用方式: ```sql -CREATE [GLOBAL | SESSION] BINDING FROM HISTORY USING PLAN DIGEST 'plan_digest'; +CREATE [GLOBAL | SESSION] BINDING FROM HISTORY USING PLAN DIGEST StringLiteralOrUserVariableList; ``` -该语句使用 `plan_digest` 为 SQL 语句绑定执行计划,在不指定作用域时默认作用域为 SESSION。所创建绑定的适用 SQL、优先级、作用域、生效条件等与[根据 SQL 创建绑定](#根据-sql-创建绑定)相同。 +该语句使用 Plan Digest 为 SQL 语句绑定执行计划,在不指定作用域时默认作用域为 SESSION。所创建绑定的适用 SQL、优先级、作用域、生效条件等与[根据 SQL 创建绑定](#根据-sql-创建绑定)相同。 -使用此绑定方式时,你需要先从 `statements_summary` 中找到需要绑定的执行计划对应的 `plan_digest`,再通过 `plan_digest` 创建绑定。具体步骤如下: +使用此绑定方式时,你需要先从 `statements_summary` 中找到需要绑定的执行计划对应的 Plan Digest,再通过 Plan Digest 创建绑定。具体步骤如下: -1. 从 `Statement Summary Tables` 的记录中查找执行计划对应的 `plan_digest`。 +1. 从 `Statement Summary Tables` 的记录中查找执行计划对应的 Plan Digest。 - 例如: + 例如: ```sql CREATE TABLE t(id INT PRIMARY KEY , a INT, KEY(a)); @@ -266,9 +266,9 @@ CREATE [GLOBAL | SESSION] BINDING FROM HISTORY USING PLAN DIGEST 'plan_digest'; BINARY_PLAN: 6QOYCuQDCg1UYWJsZVJlYWRlcl83Ev8BCgtTZWxlY3Rpb25fNhKOAQoPBSJQRnVsbFNjYW5fNSEBAAAAOA0/QSkAAQHwW4jDQDgCQAJKCwoJCgR0ZXN0EgF0Uh5rZWVwIG9yZGVyOmZhbHNlLCBzdGF0czpwc2V1ZG9qInRpa3ZfdGFzazp7dGltZTo1NjAuOMK1cywgbG9vcHM6MH1w////CQMEAXgJCBD///8BIQFzCDhVQw19BAAkBX0QUg9lcSgBfCAudC5hLCAxKWrmYQAYHOi0gc6hBB1hJAFAAVIQZGF0YTo9GgRaFAW4HDQuMDVtcywgCbYcMWKEAWNvcF8F2agge251bTogMSwgbWF4OiA1OTguNsK1cywgcHJvY19rZXlzOiAwLCBycGNfBSkAMgkMBVcQIDYwOS4pEPBDY29wcl9jYWNoZV9oaXRfcmF0aW86IDAuMDAsIGRpc3RzcWxfY29uY3VycmVuY3k6IDE1fXCwAXj///////////8BGAE= ``` - 可以看到执行计划对应的 `plan_digest` 为 `4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb`。 + 可以看到执行计划对应的 Plan Digest 为 `4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb`。 -2. 使用 `plan_digest` 创建绑定。 +2. 使用 Plan Digest 创建绑定。 ```sql CREATE BINDING FROM HISTORY USING PLAN DIGEST '4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb'; @@ -309,7 +309,7 @@ SELECT @@LAST_PLAN_FROM_BINDING; ### 删除绑定 -你可以根据 SQL 语句或者 `sql_digest` 删除绑定。 +你可以根据 SQL 语句或者 SQL Digest 删除绑定。 #### 根据 SQL 语句删除绑定 @@ -335,15 +335,15 @@ explain SELECT * FROM t1,t2 WHERE t1.id = t2.id; 在这里 SESSION 作用域内被删除掉的绑定会屏蔽 GLOBAL 作用域内相应的绑定,优化器不会为 `SELECT` 语句添加 `sm_join(t1, t2)` hint,`explain` 给出的执行计划中最上层节点并不被 hint 固定为 MergeJoin,而是由优化器经过代价估算后自主进行选择。 -#### 根据 `sql_digest` 删除绑定 +#### 根据 SQL Digest 删除绑定 -除了可以根据 SQL 语句删除对应的绑定以外,也可以根据 `sql_digest` 删除绑定: +你既可以根据 SQL 语句删除对应的绑定,也可以根据 SQL Digest 删除绑定。详细说明和更多示例参见 [`DROP [GLOBAL|SESSION] BINDING`](/sql-statements/sql-statement-drop-binding.md)。 ```sql -DROP [GLOBAL | SESSION] BINDING FOR SQL DIGEST 'sql_digest'; +DROP [GLOBAL | SESSION] BINDING FOR SQL DIGEST StringLiteralOrUserVariableList; ``` -该语句用于在 GLOBAL 或者 SESSION 作用域内删除 `sql_digest` 对应的的执行计划绑定,在不指定作用域时默认作用域为 SESSION。你可以通过[查看绑定](#查看绑定)语句获取 `sql_digest`。 +该语句用于在 GLOBAL 或者 SESSION 作用域内删除 SQL Digest 对应的的执行计划绑定,在不指定作用域时默认作用域为 SESSION。你可以通过[查看绑定](#查看绑定)语句获取 SQL Digest。 > **注意:** > diff --git a/sql-statements/sql-statement-create-binding.md b/sql-statements/sql-statement-create-binding.md index b177253f46cf..daa8aa7f25cc 100644 --- a/sql-statements/sql-statement-create-binding.md +++ b/sql-statements/sql-statement-create-binding.md @@ -17,21 +17,30 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-create-binding/'] ```ebnf+diagram CreateBindingStmt ::= 'CREATE' GlobalScope 'BINDING' ( 'FOR' BindableStmt 'USING' BindableStmt -| 'FROM' 'HISTORY' 'USING' 'PLAN' 'DIGEST' PlanDigest ) +| 'FROM' 'HISTORY' 'USING' 'PLAN' 'DIGEST' StringLiteralOrUserVariableList ) GlobalScope ::= ( 'GLOBAL' | 'SESSION' )? BindableStmt ::= ( SelectStmt | UpdateStmt | InsertIntoStmt | ReplaceIntoStmt | DeleteStmt ) -``` -**** +StringLiteralOrUserVariableList ::= + ( StringLitOrUserVariable | StringLiteralOrUserVariableList ',' StringLitOrUserVariable ) + +StringLiteralOrUserVariable ::= + ( stringLiteral | UserVariable ) +``` ## 示例 你可以根据 SQL 或历史执行计划创建绑定。 +根据历史执行计划创建绑定时,你需要指定相应的 Plan Digest: + +- 既可以通过字符串字面量来指定,也可以通过字符串类型的用户变量来指定。 +- 可以通过指定多个 Plan Digest 来同时为多个语句创建绑定。此时你可以指定多个字符串,同时每个字符串也可以包含多个 digest,注意字符串之间和 digest 之间均需使用逗号隔开。 + 下面的示例演示如何根据 SQL 创建绑定。 {{< copyable "sql" >}} @@ -139,34 +148,165 @@ EXPLAIN ANALYZE SELECT * FROM t1 WHERE b = 123; 下面的示例演示如何根据历史执行计划创建绑定。 ```sql -mysql> CREATE TABLE t(id INT PRIMARY KEY , a INT, KEY(a)); -Query OK, 0 rows affected (0.06 sec) +USE test; +CREATE TABLE t1(a INT, b INT, c INT, INDEX ia(a)); +CREATE TABLE t2(a INT, b INT, c INT, INDEX ia(a)); +INSERT INTO t1 SELECT * FROM t2 WHERE a = 1; +SELECT @@LAST_PLAN_FROM_BINDING; +UPDATE /*+ INL_JOIN(t2) */ t1, t2 SET t1.a = 1 WHERE t1.b = t2.a; +SELECT @@LAST_PLAN_FROM_BINDING; +DELETE /*+ HASH_JOIN(t1) */ t1 FROM t1 JOIN t2 WHERE t1.b = t2.a; +SELECT @@LAST_PLAN_FROM_BINDING; +SELECT * FROM t1 WHERE t1.a IN (SELECT a FROM t2); +SELECT @@LAST_PLAN_FROM_BINDING; +``` + +方法一: + +```sql +SELECT query_sample_text, stmt_type, table_names, plan_digest FROM information_schema.statements_summary_history WHERE table_names LIKE '%test.t1%' AND stmt_type != 'CreateTable'; +CREATE GLOBAL BINDING FROM HISTORY USING PLAN DIGEST 'e72819cf99932f63a548156dbf433adda60e10337e89dcaa8638b4caf16f64d8,c291edc36b2482738d3389d335f37efc76290be2930330fe5034c5f4c42eeb36,8dc146249484f4a6ab219bfe9effa6b7a18aeed3764d49b610da61ac347ab914,73b2dec866595688ea416675f88ccb3456eb8e7443a79cd816695b688e07ac6b'; +``` + +方法二: + +```sql +SELECT @digests:=GROUP_CONCAT(plan_digest) FROM information_schema.statements_summary_history WHERE table_names LIKE '%test.t1%' AND stmt_type != 'CreateTable'; +CREATE GLOBAL BINDING FROM HISTORY USING PLAN DIGEST @digests; +``` + +```sql +SHOW GLOBAL BINDINGS; +INSERT INTO t1 SELECT * FROM t2 WHERE a = 1; +SELECT @@LAST_PLAN_FROM_BINDING; +UPDATE t1, t2 SET t1.a = 1 WHERE t1.b = t2.a; +SELECT @@LAST_PLAN_FROM_BINDING; +DELETE t1 FROM t1 JOIN t2 WHERE t1.b = t2.a; +SELECT @@LAST_PLAN_FROM_BINDING; +SELECT * FROM t1 WHERE t1.a IN (SELECT a FROM t2); +SELECT @@LAST_PLAN_FROM_BINDING; +``` + +```sql +> CREATE TABLE t1(a INT, b INT, c INT, INDEX ia(a)); +Query OK, 0 rows affected (0.048 sec) -mysql> SELECT /*+ IGNORE_INDEX(t, a) */ * FROM t WHERE a = 1; -Empty set (0.01 sec) +> CREATE TABLE t2(a INT, b INT, c INT, INDEX ia(a)); +Query OK, 0 rows affected (0.035 sec) -mysql> SELECT plan_digest FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY WHERE QUERY_SAMPLE_TEXT = 'SELECT /*+ IGNORE_INDEX(t, a) */ * FROM t WHERE a = 1'; -+------------------------------------------------------------------+ -| plan_digest | -+------------------------------------------------------------------+ -| 4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb | -+------------------------------------------------------------------+ -1 row in set (0.01 sec) +> INSERT INTO t1 SELECT * FROM t2 WHERE a = 1; +Query OK, 0 rows affected (0.002 sec) +Records: 0 Duplicates: 0 Warnings: 0 -mysql> CREATE BINDING FROM HISTORY USING PLAN DIGEST '4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb'; -Query OK, 0 rows affected (0.02 sec) +> SELECT @@LAST_PLAN_FROM_BINDING; ++--------------------------+ +| @@LAST_PLAN_FROM_BINDING | ++--------------------------+ +| 0 | ++--------------------------+ +1 row in set (0.001 sec) -mysql> SELECT * FROM t WHERE a = 1; -Empty set (0.01 sec) +> UPDATE /*+ INL_JOIN(t2) */ t1, t2 SET t1.a = 1 WHERE t1.b = t2.a; +Query OK, 0 rows affected (0.005 sec) +Rows matched: 0 Changed: 0 Warnings: 0 -mysql> SELECT @@LAST_PLAN_FROM_BINDING; +> SELECT @@LAST_PLAN_FROM_BINDING; ++--------------------------+ +| @@LAST_PLAN_FROM_BINDING | ++--------------------------+ +| 0 | ++--------------------------+ +1 row in set (0.000 sec) + +> DELETE /*+ HASH_JOIN(t1) */ t1 FROM t1 JOIN t2 WHERE t1.b = t2.a; +Query OK, 0 rows affected (0.003 sec) + +> SELECT @@LAST_PLAN_FROM_BINDING; ++--------------------------+ +| @@LAST_PLAN_FROM_BINDING | ++--------------------------+ +| 0 | ++--------------------------+ +1 row in set (0.000 sec) + +> SELECT * FROM t1 WHERE t1.a IN (SELECT a FROM t2); +Empty set (0.002 sec) + +> SELECT @@LAST_PLAN_FROM_BINDING; ++--------------------------+ +| @@LAST_PLAN_FROM_BINDING | ++--------------------------+ +| 0 | ++--------------------------+ +1 row in set (0.001 sec) + +> SELECT @digests:=GROUP_CONCAT(plan_digest) FROM information_schema.statements_summary_history WHERE table_names LIKE '%test.t1%' AND stmt_type != 'CreateTable'; ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| @digests:=GROUP_CONCAT(plan_digest) | ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| 73b2dec866595688ea416675f88ccb3456eb8e7443a79cd816695b688e07ac6b,8dc146249484f4a6ab219bfe9effa6b7a18aeed3764d49b610da61ac347ab914,c291edc36b2482738d3389d335f37efc76290be2930330fe5034c5f4c42eeb36,e72819cf99932f63a548156dbf433adda60e10337e89dcaa8638b4caf16f64d8 | ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +1 row in set (0.001 sec) + +> CREATE GLOBAL BINDING FROM HISTORY USING PLAN DIGEST @digests; +Query OK, 0 rows affected (0.060 sec) + +> SHOW GLOBAL BINDINGS; ++----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+-----------------+---------+------------------------------------------------------------------+------------------------------------------------------------------+ +| Original_sql | Bind_sql | Default_db | Status | Create_time | Update_time | Charset | Collation | Source | Sql_digest | Plan_digest | ++----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+-----------------+---------+------------------------------------------------------------------+------------------------------------------------------------------+ +| insert into `test` . `t1` select * from `test` . `t2` where `a` = ? | INSERT INTO `test`.`t1` SELECT /*+ use_index(@`sel_1` `test`.`t2` `ia`) no_order_index(@`sel_1` `test`.`t2` `ia`)*/ * FROM `test`.`t2` WHERE `a` = 1 | test | enabled | 2024-08-11 05:27:19.669 | 2024-08-11 05:27:19.669 | utf8 | utf8_general_ci | history | bd23e6af17e7b77b25383e50e258f0dece18583d19772f08caacb2021945a300 | e72819cf99932f63a548156dbf433adda60e10337e89dcaa8638b4caf16f64d8 | +| update ( `test` . `t1` ) join `test` . `t2` set `t1` . `a` = ? where `t1` . `b` = `t2` . `a` | UPDATE /*+ inl_join(`test`.`t2`) use_index(@`upd_1` `test`.`t1` ) use_index(@`upd_1` `test`.`t2` `ia`) no_order_index(@`upd_1` `test`.`t2` `ia`)*/ (`test`.`t1`) JOIN `test`.`t2` SET `t1`.`a`=1 WHERE `t1`.`b` = `t2`.`a` | test | enabled | 2024-08-11 05:27:19.667 | 2024-08-11 05:27:19.667 | utf8 | utf8_general_ci | history | 987e91af17eb40e36fecfc0634cce0b6a736de02bb009091810f932804fc02e9 | c291edc36b2482738d3389d335f37efc76290be2930330fe5034c5f4c42eeb36 | +| delete `test` . `t1` from `test` . `t1` join `test` . `t2` where `t1` . `b` = `t2` . `a` | DELETE /*+ hash_join_build(`test`.`t2`) use_index(@`del_1` `test`.`t1` ) use_index(@`del_1` `test`.`t2` )*/ `test`.`t1` FROM `test`.`t1` JOIN `test`.`t2` WHERE `t1`.`b` = `t2`.`a` | test | enabled | 2024-08-11 05:27:19.664 | 2024-08-11 05:27:19.664 | utf8 | utf8_general_ci | history | 70ef3d442d95c51020a76c7c86a3ab674258606d4dd24bbd16ac6f69d87a4316 | 8dc146249484f4a6ab219bfe9effa6b7a18aeed3764d49b610da61ac347ab914 | +| select * from `test` . `t1` where `t1` . `a` in ( select `a` from `test` . `t2` ) | SELECT /*+ use_index(@`sel_1` `test`.`t1` ) stream_agg(@`sel_2`) use_index(@`sel_2` `test`.`t2` `ia`) order_index(@`sel_2` `test`.`t2` `ia`) agg_to_cop(@`sel_2`)*/ * FROM `test`.`t1` WHERE `t1`.`a` IN (SELECT `a` FROM `test`.`t2`) | test | enabled | 2024-08-11 05:27:19.649 | 2024-08-11 05:27:19.649 | utf8 | utf8_general_ci | history | b58508a5e29d7889adf98cad50343d7a575fd32ad55dbdaa88e14ecde54f3d93 | 73b2dec866595688ea416675f88ccb3456eb8e7443a79cd816695b688e07ac6b | ++----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+-----------------+---------+------------------------------------------------------------------+------------------------------------------------------------------+ +4 rows in set (0.001 sec) + +> INSERT INTO t1 SELECT * FROM t2 WHERE a = 1; +Query OK, 0 rows affected (0.002 sec) +Records: 0 Duplicates: 0 Warnings: 0 + +> SELECT @@LAST_PLAN_FROM_BINDING; +--------------------------+ | @@LAST_PLAN_FROM_BINDING | +--------------------------+ | 1 | +--------------------------+ -1 row in set (0.01 sec) +1 row in set (0.000 sec) + +> UPDATE t1, t2 SET t1.a = 1 WHERE t1.b = t2.a; +Query OK, 0 rows affected (0.002 sec) +Rows matched: 0 Changed: 0 Warnings: 0 +> SELECT @@LAST_PLAN_FROM_BINDING; ++--------------------------+ +| @@LAST_PLAN_FROM_BINDING | ++--------------------------+ +| 1 | ++--------------------------+ +1 row in set (0.000 sec) + +> DELETE t1 FROM t1 JOIN t2 WHERE t1.b = t2.a; +Query OK, 0 rows affected (0.002 sec) + +> SELECT @@LAST_PLAN_FROM_BINDING; ++--------------------------+ +| @@LAST_PLAN_FROM_BINDING | ++--------------------------+ +| 1 | ++--------------------------+ +1 row in set (0.000 sec) + +> SELECT * FROM t1 WHERE t1.a IN (SELECT a FROM t2); +Empty set (0.002 sec) + +> SELECT @@LAST_PLAN_FROM_BINDING; ++--------------------------+ +| @@LAST_PLAN_FROM_BINDING | ++--------------------------+ +| 1 | ++--------------------------+ +1 row in set (0.002 sec) ``` ## MySQL 兼容性 diff --git a/sql-statements/sql-statement-drop-binding.md b/sql-statements/sql-statement-drop-binding.md index 860c8ac30def..6891b4f88e55 100644 --- a/sql-statements/sql-statement-drop-binding.md +++ b/sql-statements/sql-statement-drop-binding.md @@ -15,18 +15,29 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-drop-binding/'] ```ebnf+diagram DropBindingStmt ::= 'DROP' GlobalScope 'BINDING' 'FOR' ( BindableStmt ( 'USING' BindableStmt )? -| 'SQL' 'DIGEST' SqlDigest) +| 'SQL' 'DIGEST' StringLiteralOrUserVariableList ) GlobalScope ::= ( 'GLOBAL' | 'SESSION' )? BindableStmt ::= ( SelectStmt | UpdateStmt | InsertIntoStmt | ReplaceIntoStmt | DeleteStmt ) + +StringLiteralOrUserVariableList ::= + ( StringLitOrUserVariable | StringLiteralOrUserVariableList ',' StringLitOrUserVariable ) + +StringLiteralOrUserVariable ::= + ( stringLiteral | UserVariable ) ``` ## 示例 -你可以根据 SQL 语句或 `sql_digest` 删除绑定。 +你可以根据 SQL 语句或 SQL Digest 删除绑定。 + +根据 SQL Digest 删除绑定时,你需要指定相应的 SQL Digest: + +- 既可以通过字符串字面量来指定,也可以通过字符串类型的用户变量来指定。 +- 可以指定多个字符串,同时每个字符串也可以包含多个 digest,注意字符串之间和 digest 之间均需使用逗号隔开。 下面的示例演示如何根据 SQL 语句删除绑定。 @@ -135,63 +146,63 @@ SHOW SESSION BINDINGS\G Empty set (0.00 sec) ``` -下面的示例演示如何根据 `sql_digest` 删除绑定。 +下面的示例演示如何根据 SQL Digest 删除绑定。 ```sql -mysql> CREATE TABLE t(id INT PRIMARY KEY , a INT, KEY(a)); -Query OK, 0 rows affected (0.06 sec) - -mysql> SELECT /*+ IGNORE_INDEX(t, a) */ * FROM t WHERE a = 1; -Empty set (0.01 sec) - -mysql> SELECT plan_digest FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY WHERE QUERY_SAMPLE_TEXT = 'SELECT /*+ IGNORE_INDEX(t, a) */ * FROM t WHERE a = 1'; -+------------------------------------------------------------------+ -| plan_digest | -+------------------------------------------------------------------+ -| 4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb | -+------------------------------------------------------------------+ -1 row in set (0.01 sec) - -mysql> CREATE BINDING FROM HISTORY USING PLAN DIGEST '4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb'; -Query OK, 0 rows affected (0.02 sec) - -mysql> SELECT * FROM t WHERE a = 1; -Empty set (0.01 sec) - -mysql> SELECT @@LAST_PLAN_FROM_BINDING; -+--------------------------+ -| @@LAST_PLAN_FROM_BINDING | -+--------------------------+ -| 1 | -+--------------------------+ -1 row in set (0.01 sec) - -mysql> SHOW BINDINGS\G -*************************** 1. row *************************** -Original_sql: select * from `test` . `t` where `a` = ? - Bind_sql: SELECT /*+ use_index(@`sel_1` `test`.`t` ) ignore_index(`t` `a`)*/ * FROM `test`.`t` WHERE `a` = 1 - Default_db: test - Status: enabled - Create_time: 2022-12-14 15:26:22.277 - Update_time: 2022-12-14 15:26:22.277 - Charset: utf8mb4 - Collation: utf8mb4_general_ci - Source: history - Sql_digest: 6909a1bbce5f64ade0a532d7058dd77b6ad5d5068aee22a531304280de48349f - Plan_digest: 4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb -1 row in set (0.02 sec) +CREATE TABLE t1(a INT, b INT, c INT, INDEX ia(a)); +CREATE TABLE t2(a INT, b INT, c INT, INDEX ia(a)); +CREATE GLOBAL BINDING FOR SELECT * FROM t1 WHERE a > 1 USING SELECT * FROM t1 USE INDEX (ia) WHERE a > 1; +CREATE GLOBAL BINDING FOR SELECT * FROM t2 WHERE a < 1 USING SELECT * FROM t2 USE INDEX (ia) WHERE a < 1; +CREATE GLOBAL BINDING FOR SELECT * FROM t1 JOIN t2 ON t1.b = t2.a USING SELECT /*+ HASH_JOIN(t1) */ * FROM t1 JOIN t2 ON t1.b = t2.a; +SHOW GLOBAL BINDINGS; +``` -ERROR: -No query specified +方法一: -mysql> DROP BINDING FOR SQL DIGEST '6909a1bbce5f64ade0a532d7058dd77b6ad5d5068aee22a531304280de48349f'; -Query OK, 0 rows affected (0.00 sec) +```sql +DROP GLOBAL BINDING FOR SQL DIGEST '31026623c8f22264fe0dfc26f29c69c5c457d6b85960c578ebcf17a967ed7893', '0f38b2e769927ae37981c66f0988c6299b602e03f029e38aa071e656fc321593', '3c8dfc451b0e36afd904cefca5137e68fb051f02964e1958ed60afdadc25f57e'; +SHOW GLOBAL BINDINGS; +``` + +方法二: + +```sql +SET @digests='31026623c8f22264fe0dfc26f29c69c5c457d6b85960c578ebcf17a967ed7893, 0f38b2e769927ae37981c66f0988c6299b602e03f029e38aa071e656fc321593, 3c8dfc451b0e36afd904cefca5137e68fb051f02964e1958ed60afdadc25f57e'; +DROP GLOBAL BINDING FOR SQL DIGEST @digests; +SHOW GLOBAL BINDINGS; +``` + +```sql +> CREATE TABLE t1(a INT, b INT, c INT, INDEX ia(a)); +Query OK, 0 rows affected (0.044 sec) + +> CREATE TABLE t2(a INT, b INT, c INT, INDEX ia(a)); +Query OK, 0 rows affected (0.035 sec) + +> CREATE GLOBAL BINDING FOR SELECT * FROM t1 WHERE a > 1 USING SELECT * FROM t1 USE INDEX (ia) WHERE a > 1; +Query OK, 0 rows affected (0.011 sec) + +> CREATE GLOBAL BINDING FOR SELECT * FROM t2 WHERE a < 1 USING SELECT * FROM t2 USE INDEX (ia) WHERE a < 1; +Query OK, 0 rows affected (0.013 sec) + +> CREATE GLOBAL BINDING FOR SELECT * FROM t1 JOIN t2 ON t1.b = t2.a USING SELECT /*+ HASH_JOIN(t1) */ * FROM t1 JOIN t2 ON t1.b = t2.a; +Query OK, 0 rows affected (0.012 sec) + +> SHOW GLOBAL BINDINGS; ++---------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+-----------------+--------+------------------------------------------------------------------+-------------+ +| Original_sql | Bind_sql | Default_db | Status | Create_time | Update_time | Charset | Collation | Source | Sql_digest | Plan_digest | ++---------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+-----------------+--------+------------------------------------------------------------------+-------------+ +| select * from `test` . `t1` join `test` . `t2` on `t1` . `b` = `t2` . `a` | SELECT /*+ HASH_JOIN(`t1`)*/ * FROM `test`.`t1` JOIN `test`.`t2` ON `t1`.`b` = `t2`.`a` | test | enabled | 2024-08-11 04:06:49.953 | 2024-08-11 04:06:49.953 | utf8 | utf8_general_ci | manual | 31026623c8f22264fe0dfc26f29c69c5c457d6b85960c578ebcf17a967ed7893 | | +| select * from `test` . `t2` where `a` < ? | SELECT * FROM `test`.`t2` USE INDEX (`ia`) WHERE `a` < 1 | test | enabled | 2024-08-11 04:06:49.937 | 2024-08-11 04:06:49.937 | utf8 | utf8_general_ci | manual | 0f38b2e769927ae37981c66f0988c6299b602e03f029e38aa071e656fc321593 | | +| select * from `test` . `t1` where `a` > ? | SELECT * FROM `test`.`t1` USE INDEX (`ia`) WHERE `a` > 1 | test | enabled | 2024-08-11 04:06:49.924 | 2024-08-11 04:06:49.924 | utf8 | utf8_general_ci | manual | 3c8dfc451b0e36afd904cefca5137e68fb051f02964e1958ed60afdadc25f57e | | ++---------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+-----------------+--------+------------------------------------------------------------------+-------------+ +3 rows in set (0.001 sec) -mysql> SHOW BINDINGS\G -Empty set (0.01 sec) +> DROP GLOBAL BINDING FOR SQL DIGEST '31026623c8f22264fe0dfc26f29c69c5c457d6b85960c578ebcf17a967ed7893', '0f38b2e769927ae37981c66f0988c6299b602e03f029e38aa071e656fc321593', '3c8dfc451b0e36afd904cefca5137e68fb051f02964e1958ed60afdadc25f57e'; +Query OK, 3 rows affected (0.019 sec) -ERROR: -No query specified +> SHOW GLOBAL BINDINGS; +Empty set (0.002 sec) ``` ## MySQL 兼容性