Description:
select covering index columns use same condition but result is different.When use WHERE c3 >= 40 and 0<c1<3 and WHERE c3 >= 40 and 0<c1 and c1<3,c1 is prefix column,c3 is after column,but same condition make different mm tree.
c3 >= 40 and 0<c1<3 ===> c3 >= 40
c3 >= 40 and 0<c1 and c1<3 ===> c3 >= 40 ->next_key_part 0<c1<3
and then c3 >= 40 can use skip scan,but 0<c1<3 can't.
How to repeat:
CREATE TABLE t1(c1 INT, c2 INT, c3 INT, c4 INT);
CREATE UNIQUE INDEX i1_t1 ON t1(c1,c2,c3);
INSERT INTO t1 VALUES (1,1,1,1), (1,1,2,2), (1,3,3,3), (1,4,4,4), (1,5,5,5),
(2,1,1,1), (2,2,2,2), (2,3,3,3), (2,4,4,4), (2,5,5,5);
INSERT INTO t1 SELECT c1, c2, c3+5, c4+10 FROM t1;
INSERT INTO t1 SELECT c1, c2, c3+10, c4+20 FROM t1;
INSERT INTO t1 SELECT c1, c2, c3+20, c4+40 FROM t1;
INSERT INTO t1 SELECT c1, c2, c3+40, c4+80 FROM t1;
ANALYZE TABLE t1;
> EXPLAIN SELECT c1, c2,c3 FROM t1 WHERE c3 >= 40 and 0<c1<3;
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------------+
| 1 | SIMPLE | t1 | NULL | range | i1_t1 | i1_t1 | 15 | NULL | 53 | 100.00 | Using where; Using index for skip scan |
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------------+
> EXPLAIN SELECT c1, c2,c3 FROM t1 WHERE c3 >= 40 and 0<c1 and c1<3;
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | t1 | NULL | index | i1_t1 | i1_t1 | 15 | NULL | 160 | 33.33 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+--------------------------+
Suggested fix:
in range_analysis.cc:
get_mm_tree() {
default: {
Item *const arg_left = cond_func->arguments()[0];
assert(!ftree);
if (!arg_left->is_outer_reference() &&
arg_left->real_item()->type() == Item::FIELD_ITEM) {
}
}
the problem is arg_left->real_item()->type() == Item::FIELD_ITEM,for Item 0<c1<3,
arg_left is Item_func_le and arg_right is 3,so it can't do get_full_func_mm_tree(),so Item 0<c1<3 can't make mm tree.