Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ExtractEqAndInCondition use conditions without user vars to build range for plan cache #34561

Closed
time-and-fate opened this issue May 11, 2022 · 2 comments
Assignees
Labels
epic/plan-cache sig/planner SIG: Planner type/enhancement The issue or PR belongs to an enhancement.

Comments

@time-and-fate
Copy link
Member

Enhancement

Currently, in ExtractEqAndInCondition(), if user variables can possibly affect the correctness of the plan for plan cache, we will give up building any access conditions (which will become table/index range scan), and mark all conditions as filter conditions (which will become filters in the selection operator).

However, even when there're user variables in some conditions, we can use the conditions that don't contain user variables to build access conditions. This will avoid some unnecessary table/index full scans when the plan cache is enabled.

@time-and-fate time-and-fate added type/enhancement The issue or PR belongs to an enhancement. sig/planner SIG: Planner epic/plan-cache labels May 11, 2022
@qw4990
Copy link
Contributor

qw4990 commented Aug 16, 2022

An example:

mysql> create table t (a int, key(a));
Query OK, 0 rows affected (0.02 sec)

mysql> prepare stmt from 'select * from t where a>? and a<?';
Query OK, 0 rows affected (0.00 sec)

mysql> set @x=10, @y=5;
Query OK, 0 rows affected (0.00 sec)

mysql> execute stmt using @x, @y;
Empty set (0.00 sec)

mysql> execute stmt using @y, @x;
Empty set (0.00 sec)

And

mysql> explain for connection 2199023255955; -- plan of the first execution
+---------------------------+----------+---------+-----------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+--------+------+
| id                        | estRows  | actRows | task      | access object | execution info                                                                                                                                               | operator info                     | memory | disk |
+---------------------------+----------+---------+-----------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+--------+------+
| Selection_8               | 0.00     | 0       | root      |               | time:330.3µs, loops:1                                                                                                                                        | gt(test.t.a, 10), lt(test.t.a, 5) | N/A    | N/A  |
| └─TableReader_7           | 0.00     | 0       | root      |               | time:329.8µs, loops:1, cop_task: {num: 1, max: 273.4µs, proc_keys: 0, rpc_num: 1, rpc_time: 256.8µs, copr_cache_hit_ratio: 0.00, distsql_concurrency: 15}    | data:Selection_6                  | N/A    | N/A  |
|   └─Selection_6           | 0.00     | 0       | cop[tikv] |               | tikv_task:{time:243.1µs, loops:0}                                                                                                                            | gt(test.t.a, 10), lt(test.t.a, 5) | N/A    | N/A  |
|     └─TableFullScan_5     | 10000.00 | 0       | cop[tikv] | table:t       | tikv_task:{time:243.1µs, loops:0}                                                                                                                            | keep order:false, stats:pseudo    | N/A    | N/A  |
+---------------------------+----------+---------+-----------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+--------+------+

mysql> explain for connection 2199023255955; -- plan of the second execution
+---------------------------+----------+---------+-----------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+--------+------+
| id                        | estRows  | actRows | task      | access object | execution info                                                                                                                                               | operator info                     | memory | disk |
+---------------------------+----------+---------+-----------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+--------+------+
| Selection_8               | 0.00     | 0       | root      |               | time:770.6µs, loops:1                                                                                                                                        | gt(test.t.a, 5), lt(test.t.a, 10) | N/A    | N/A  |
| └─TableReader_7           | 0.00     | 0       | root      |               | time:768.3µs, loops:1, cop_task: {num: 1, max: 647.3µs, proc_keys: 0, rpc_num: 1, rpc_time: 592.7µs, copr_cache_hit_ratio: 0.00, distsql_concurrency: 15}    | data:Selection_6                  | N/A    | N/A  |
|   └─Selection_6           | 0.00     | 0       | cop[tikv] |               | tikv_task:{time:557.4µs, loops:0}                                                                                                                            | gt(test.t.a, 5), lt(test.t.a, 10) | N/A    | N/A  |
|     └─TableFullScan_5     | 10000.00 | 0       | cop[tikv] | table:t       | tikv_task:{time:557.4µs, loops:0}                                                                                                                            | keep order:false, stats:pseudo    | N/A    | N/A  |
+---------------------------+----------+---------+-----------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+--------+------+

A better choice of the second execution is to use RangeScan instead of FullScan.

@qw4990
Copy link
Contributor

qw4990 commented Jan 4, 2023

Fixed by #28944

@qw4990 qw4990 closed this as completed Jan 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epic/plan-cache sig/planner SIG: Planner type/enhancement The issue or PR belongs to an enhancement.
Projects
None yet
Development

No branches or pull requests

3 participants