pingcap/tidb
在 GitHub 查看Allow filter condition push down to IndexScan for prefix index.
Open
#21,145 创建于 2020年11月19日
help wantedsig/plannertype/feature-request
仓库指标
- Star
- (40,090 star)
- PR 合并指标
- (平均合并 14天 4小时) (30 天内合并 346 个 PR)
描述
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: