First I tried torun the reported query for 10.4 with optimizer trace enabled after the following changes for default settings:
set optimizer_switch='index_merge=off';
|
set optimizer_switch='rowid_filter=off';
|
set optimizer_use_condition_selectivity=1;
|
.
The optimizer trace for the query showed that no range condition was extracted for the index incident_indexi0. I changed the WHERE condition to a much simpler OR formula and still could not get range condition for the index. It's interesting that swapping operands in this formula led to the choice the wanted range scan for this index.
After this I came up with a simple test case demonstrating the problem:
create table t1 (
|
pk int primary key auto_increment, a int, b int,
|
index idx1(a), index idx2(b)
|
) engine=myisam;
|
insert into t1(a,b) values
|
(5,50), (1,10), (3,30), (7,70), (8,80), (4,40), (2,20), (6,60);
|
insert into t1(a,b) select a+10, b+100 from t1;
|
insert into t1(a,b) select a+20, b+200 from t1;
|
insert into t1(a,b) select a+30, b+300 from t1;
|
insert into t1(a,b) select a,b from t1;
|
explain select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
|
The optimizer chose a full table scan:
MariaDB [test]> explain select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
|
+------+-------------+-------+------+---------------+------+---------+------+------+-------------+
|
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|
+------+-------------+-------+------+---------------+------+---------+------+------+-------------+
|
| 1 | SIMPLE | t1 | ALL | idx1,idx2 | NULL | NULL | NULL | 64 | Using where |
|
+------+-------------+-------+------+---------------+------+---------+------+------+-------------+
|
though for the following equivalent query a range scan was chosen:
MariaDB [test]> explain select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
|
+------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------+
|
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|
+------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------+
|
| 1 | SIMPLE | t1 | range | idx1,idx2 | idx1 | 5 | NULL | 4 | Using index condition; Using where |
|
+------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------+
|
First I tried torun the reported query for 10.4 with optimizer trace enabled after the following changes for default settings:
.
The optimizer trace for the query showed that no range condition was extracted for the index incident_indexi0. I changed the WHERE condition to a much simpler OR formula and still could not get range condition for the index. It's interesting that swapping operands in this formula led to the choice the wanted range scan for this index.
After this I came up with a simple test case demonstrating the problem:
) engine=myisam;
(5,50), (1,10), (3,30), (7,70), (8,80), (4,40), (2,20), (6,60);
The optimizer chose a full table scan:
MariaDB [test]> explain select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
+------+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | t1 | ALL | idx1,idx2 | NULL | NULL | NULL | 64 | Using where |
+------+-------------+-------+------+---------------+------+---------+------+------+-------------+
though for the following equivalent query a range scan was chosen:
MariaDB [test]> explain select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
+------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------+
| 1 | SIMPLE | t1 | range | idx1,idx2 | idx1 | 5 | NULL | 4 | Using index condition; Using where |
+------+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------+