mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 03:17:20 +02:00
MDEV-38327 Do not use rowid filter in ref_to_range when the range method is index merge
Index merge and rowid filter should not be used together, however, even if index merge is not chosen earlier in best_access_path, it may be chosen again in make_join_select, inside ref_to_range. Therefore this patch ensures that rowid filter is not used when index merge is chosen there.
This commit is contained in:
parent
6229192647
commit
2c2a418591
4 changed files with 183 additions and 0 deletions
|
|
@ -973,3 +973,69 @@ f1 f4 f5
|
|||
DROP TABLE t1;
|
||||
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
|
||||
SET SESSION optimizer_switch='rowid_filter=default';
|
||||
#
|
||||
# MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on
|
||||
#
|
||||
CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d));
|
||||
INSERT INTO t1
|
||||
SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ;
|
||||
explain select a, b, c from t1 where a=1000 and b=1001000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
|
||||
select a, b, c from t1 where a=1000 and b=1001000;
|
||||
a b c
|
||||
1000 1001000 1005000
|
||||
1000 1001000 1005001
|
||||
1000 1001000 1005002
|
||||
1000 1001000 1005003
|
||||
1000 1001000 1005004
|
||||
set optimizer_switch='index_merge_sort_intersection=on';
|
||||
explain select a, b, c from t1 where a=1000 and b=1001000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
|
||||
select a, b, c from t1 where a=1000 and b=1001000;
|
||||
a b c
|
||||
1000 1001000 1005000
|
||||
1000 1001000 1005001
|
||||
1000 1001000 1005002
|
||||
1000 1001000 1005003
|
||||
1000 1001000 1005004
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status Table is already up to date
|
||||
explain select a, b, c from t1 where a=1000 and b=1001000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
|
||||
select a, b, c from t1 where a=1000 and b=1001000;
|
||||
a b c
|
||||
1000 1001000 1005000
|
||||
1000 1001000 1005001
|
||||
1000 1001000 1005002
|
||||
1000 1001000 1005003
|
||||
1000 1001000 1005004
|
||||
drop table t1;
|
||||
## MDEV-28878 case
|
||||
CREATE TABLE t1 (f int);
|
||||
INSERT INTO t1 VALUES (0),(4);
|
||||
CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b));
|
||||
INSERT INTO t2 VALUES
|
||||
(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'),
|
||||
(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'),
|
||||
(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m');
|
||||
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status OK
|
||||
test.t2 analyze status Engine-independent statistics collected
|
||||
test.t2 analyze status OK
|
||||
SET optimizer_switch='rowid_filter=on';
|
||||
SET optimizer_switch='index_merge_sort_intersection=off';
|
||||
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
|
||||
f pk a b
|
||||
4 3 4 p
|
||||
SET optimizer_switch='index_merge_sort_intersection=on';
|
||||
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
|
||||
f pk a b
|
||||
4 3 4 p
|
||||
DROP TABLE t1, t2;
|
||||
|
|
|
|||
|
|
@ -476,3 +476,52 @@ DROP TABLE t1;
|
|||
|
||||
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
|
||||
SET SESSION optimizer_switch='rowid_filter=default';
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on
|
||||
--echo #
|
||||
--source include/have_sequence.inc
|
||||
CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d));
|
||||
INSERT INTO t1
|
||||
SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ;
|
||||
|
||||
let $query=
|
||||
select a, b, c from t1 where a=1000 and b=1001000;
|
||||
|
||||
eval explain $query;
|
||||
eval $query;
|
||||
|
||||
set optimizer_switch='index_merge_sort_intersection=on';
|
||||
|
||||
eval explain $query;
|
||||
eval $query;
|
||||
|
||||
analyze table t1;
|
||||
|
||||
eval explain $query;
|
||||
eval $query;
|
||||
|
||||
drop table t1;
|
||||
|
||||
--echo ## MDEV-28878 case
|
||||
|
||||
CREATE TABLE t1 (f int);
|
||||
INSERT INTO t1 VALUES (0),(4);
|
||||
|
||||
CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b));
|
||||
INSERT INTO t2 VALUES
|
||||
(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'),
|
||||
(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'),
|
||||
(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m');
|
||||
|
||||
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
|
||||
|
||||
SET optimizer_switch='rowid_filter=on'; # Default
|
||||
|
||||
SET optimizer_switch='index_merge_sort_intersection=off'; # Default
|
||||
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
|
||||
|
||||
SET optimizer_switch='index_merge_sort_intersection=on';
|
||||
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
|
|
|||
|
|
@ -979,6 +979,72 @@ f1 f4 f5
|
|||
DROP TABLE t1;
|
||||
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
|
||||
SET SESSION optimizer_switch='rowid_filter=default';
|
||||
#
|
||||
# MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on
|
||||
#
|
||||
CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d));
|
||||
INSERT INTO t1
|
||||
SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ;
|
||||
explain select a, b, c from t1 where a=1000 and b=1001000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
|
||||
select a, b, c from t1 where a=1000 and b=1001000;
|
||||
a b c
|
||||
1000 1001000 1005000
|
||||
1000 1001000 1005001
|
||||
1000 1001000 1005002
|
||||
1000 1001000 1005003
|
||||
1000 1001000 1005004
|
||||
set optimizer_switch='index_merge_sort_intersection=on';
|
||||
explain select a, b, c from t1 where a=1000 and b=1001000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
|
||||
select a, b, c from t1 where a=1000 and b=1001000;
|
||||
a b c
|
||||
1000 1001000 1005000
|
||||
1000 1001000 1005001
|
||||
1000 1001000 1005002
|
||||
1000 1001000 1005003
|
||||
1000 1001000 1005004
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status OK
|
||||
explain select a, b, c from t1 where a=1000 and b=1001000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
|
||||
select a, b, c from t1 where a=1000 and b=1001000;
|
||||
a b c
|
||||
1000 1001000 1005000
|
||||
1000 1001000 1005001
|
||||
1000 1001000 1005002
|
||||
1000 1001000 1005003
|
||||
1000 1001000 1005004
|
||||
drop table t1;
|
||||
## MDEV-28878 case
|
||||
CREATE TABLE t1 (f int);
|
||||
INSERT INTO t1 VALUES (0),(4);
|
||||
CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b));
|
||||
INSERT INTO t2 VALUES
|
||||
(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'),
|
||||
(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'),
|
||||
(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m');
|
||||
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status OK
|
||||
test.t2 analyze status Engine-independent statistics collected
|
||||
test.t2 analyze status OK
|
||||
SET optimizer_switch='rowid_filter=on';
|
||||
SET optimizer_switch='index_merge_sort_intersection=off';
|
||||
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
|
||||
f pk a b
|
||||
4 3 4 p
|
||||
SET optimizer_switch='index_merge_sort_intersection=on';
|
||||
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
|
||||
f pk a b
|
||||
4 3 4 p
|
||||
DROP TABLE t1, t2;
|
||||
set global innodb_stats_persistent= @innodb_stats_persistent_save;
|
||||
set global innodb_stats_persistent_sample_pages=
|
||||
@innodb_stats_persistent_sample_pages_save;
|
||||
|
|
|
|||
|
|
@ -14456,6 +14456,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||
}
|
||||
tab->type= JT_RANGE;
|
||||
tab->use_quick=1;
|
||||
if (is_index_merge(tab->quick->get_type()))
|
||||
tab->clear_range_rowid_filter();
|
||||
tab->ref.key= -1;
|
||||
tab->ref.key_parts=0; // Don't use ref key.
|
||||
join->best_positions[i].records_read= rows2double(tab->quick->records);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue