pingcap/tidb

Allow filter condition push down to IndexScan for prefix index.

Open

#21.145 aberto em 19 de nov. de 2020

Ver no GitHub
 (4 comments) (0 reactions) (1 assignee)Go (6.186 forks)batch import
help wantedsig/plannertype/feature-request

Métricas do repositório

Stars
 (40.090 stars)
Métricas de merge de PR
 (Mesclagem média 14d 4h) (346 fundiu PRs em 30d)

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:

Guia do colaborador