pingcap/tidb
View on GitHubAllow filter condition push down to IndexScan for prefix index.
Open
#21,145 opened on Nov 19, 2020
help wantedsig/plannertype/feature-request
Description
Feature Request
Allow filter condition push down to IndexScan for prefix index.
mysql> create table t (a text, b text, index a_b (a(255), b(255)));
Query OK, 0 rows affected (0.01 sec)
mysql> explain select * from t where a between 'a' and 'b' and b = 'b';
+-------------------------------+---------+-----------+--------------------------+---------------------------------------------------------+
| id | estRows | task | access object | operator info |
+-------------------------------+---------+-----------+--------------------------+---------------------------------------------------------+
| IndexLookUp_11 | 0.25 | root | | |
| ├─IndexRangeScan_8(Build) | 250.00 | cop[tikv] | table:t, index:a_b(a, b) | range:["a","b"], keep order:false, stats:pseudo |
| └─Selection_10(Probe) | 0.25 | cop[tikv] | | eq(test.t.b, "b"), ge(test.t.a, "a"), le(test.t.a, "b") |
| └─TableRowIDScan_9 | 250.00 | cop[tikv] | table:t | keep order:false, stats:pseudo |
+-------------------------------+---------+-----------+--------------------------+---------------------------------------------------------+
The condition b = 'b' should be able to pushed down to IndexScan phase to reduce the lookup table cost.
We only need to make sure the equal condition value of b is less than the index column length 255.
The ideal plan should be
mysql> explain select * from t where a between 'a' and 'b' and b = 'b';
+--------------------------+---------+-----------+--------------------------+-------------------------------------------------+
| id | estRows | task | access object | operator info |
+--------------------------+---------+-----------+--------------------------+-------------------------------------------------+
| IndexReader_7 | 0.25 | root | | index:Selection_6 |
| └─Selection_6 | 0.25 | cop[tikv] | | eq(test.t.b, "b") |
| └─IndexRangeScan_5 | 250.00 | cop[tikv] | table:t, index:a_b(a, b) | range:["a","b"], keep order:false, stats:pseudo |
+--------------------------+---------+-----------+--------------------------+-------------------------------------------------+
Describe alternatives you've considered:
Teachability, Documentation, Adoption, Migration Strategy: