diff --git a/sql-plan-management.md b/sql-plan-management.md index 442bb2c717244..78e61453ee302 100644 --- a/sql-plan-management.md +++ b/sql-plan-management.md @@ -133,6 +133,70 @@ SELECT * FROM test . t WHERE a > ? > ``` > > 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. +> +> For example: +> +> ```sql +> CREATE TABLE t(a INT, b INT, KEY idx(a)); +> CREATE SESSION BINDING for SELECT * FROM t WHERE a IN (?) USING SELECT /*+ use_index(t, idx) */ * FROM t WHERE a in (?); +> SHOW BINDINGS; +> +-----------------------------------------------+----------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> | Original_sql | Bind_sql | Default_db | Status | Create_time | Update_time | Charset | Collation | Source | Sql_digest | Plan_digest | +> +-----------------------------------------------+----------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> | SELECT * FROM `test` . `t` WHERE `a` IN ( ? ) | SELECT /*+ use_index(`t` `idx`)*/ * FROM `test`.`t` WHERE `a` IN (?) | test | enabled | 2023-08-23 14:15:31.472 | 2023-08-23 14:15:31.472 | utf8mb4 | utf8mb4_general_ci | manual | 8b9c4e6ab8fad5ba29b034311dcbfc8a8ce57dde2e2d5d5b65313b90ebcdebf7 | | +> +-----------------------------------------------+----------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> SELECT * FROM t WHERE a IN (1); +> SELECT @@LAST_PLAN_FROM_BINDING; +> +--------------------------+ +> | @@LAST_PLAN_FROM_BINDING | +> +--------------------------+ +> | 1 | +> +--------------------------+ +> SELECT * FROM t WHERE a IN (1,2); +> SELECT @@LAST_PLAN_FROM_BINDING; +> +--------------------------+ +> | @@LAST_PLAN_FROM_BINDING | +> +--------------------------+ +> | 0 | +> +--------------------------+ +> CREATE SESSION BINDING for SELECT * FROM t WHERE a IN (?,?) USING SELECT /*+ use_index(t, idx) */ * FROM t WHERE a IN (?,?); +> show bindings; +> +-------------------------------------------------+------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> | Original_sql | Bind_sql | Default_db | Status | Create_time | Update_time | Charset | Collation | Source | Sql_digest | Plan_digest | +> +-------------------------------------------------+------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> | SELECT * FROM `test` . `t` WHERE `a` IN ( ... ) | SELECT /*+ use_index(`t` `idx`)*/ * FROM `test`.`t` WHERE `a` IN (?,?) | test | enabled | 2023-08-23 14:16:30.762 | 2023-08-23 14:16:30.762 | utf8mb4 | utf8mb4_general_ci | manual | da38bf216db4a53e1a1e01c79ffa42306419442ad7238480bb7ac510723c8bdf | | +> | SELECT * FROM `test` . `t` WHERE `a` IN ( ? ) | SELECT /*+ use_index(`t` `idx`)*/ * FROM `test`.`t` WHERE `a` IN (?) | test | enabled | 2023-08-23 14:15:31.472 | 2023-08-23 14:15:31.472 | utf8mb4 | utf8mb4_general_ci | manual | 8b9c4e6ab8fad5ba29b034311dcbfc8a8ce57dde2e2d5d5b65313b90ebcdebf7 | | +> +-------------------------------------------------+------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> SELECT * FROM t WHERE a IN (1,2); +> SELECT @@LAST_PLAN_FROM_BINDING; +> +--------------------------+ +> | @@LAST_PLAN_FROM_BINDING | +> +--------------------------+ +> | 1 | +> +--------------------------+ +> SELECT * FROM t WHERE a IN (1,2,3); +> SELECT @@LAST_PLAN_FROM_BINDING; +> +--------------------------+ +> | @@LAST_PLAN_FROM_BINDING | +> +--------------------------+ +> | 1 | +> +--------------------------+ +> DROP SESSION BINDING for SELECT * FROM t WHERE a IN (?); +> SHOW BINDINGS; +> +-------------------------------------------------+------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> | Original_sql | Bind_sql | Default_db | Status | Create_time | Update_time | Charset | Collation | Source | Sql_digest | Plan_digest | +> +-------------------------------------------------+------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> | SELECT * FROM `test` . `t` WHERE `a` IN ( ... ) | SELECT /*+ use_index(`t` `idx`)*/ * FROM `test`.`t` WHERE `a` IN (?,?) | test | enabled | 2023-08-23 14:16:30.762 | 2023-08-23 14:16:30.762 | utf8mb4 | utf8mb4_general_ci | manual | da38bf216db4a53e1a1e01c79ffa42306419442ad7238480bb7ac510723c8bdf | | +> +-------------------------------------------------+------------------------------------------------------------------------+------------+---------+-------------------------+-------------------------+---------+--------------------+--------+------------------------------------------------------------------+-------------+ +> SELECT * FROM t WHERE a IN (1); +> SELECT @@LAST_PLAN_FROM_BINDING; +> +--------------------------+ +> | @@LAST_PLAN_FROM_BINDING | +> +--------------------------+ +> | 0 | +> +--------------------------+ +> ``` +> When a SQL statement has bound execution plans in both GLOBAL and SESSION scopes, because the optimizer ignores the bound execution plan in the GLOBAL scope when it encounters the SESSION binding, the bound execution plan of this statement in the SESSION scope shields the execution plan in the GLOBAL scope.