mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
3a82c256da
Extend the fix for MDEV-25858 to handle non-reverse-ordered ORDER BY: If test_if_skip_sort_order() decides to use an index to produce rows in the required ordering, it should disable "Range Checked for Each Record". The fix needs to be backported to earlier versions.
290 lines
7.5 KiB
Text
290 lines
7.5 KiB
Text
drop table if exists t0,t1,t2,t3;
|
|
#
|
|
# MDEV-6434: Wrong result (extra rows) with ORDER BY, multiple-column index, InnoDB
|
|
#
|
|
CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB;
|
|
INSERT INTO t1 (a,c) VALUES
|
|
(8, 9),(8, 10),(13, 15),(16, 17),(16, 18),(16, 19),(20, 21),
|
|
(20, 22),(20, 24),(20, 25),(20, 26),(20, 27),(20, 28);
|
|
SELECT * FROM t1 WHERE a = 8 AND (b = 1 OR b IS NULL) ORDER BY c;
|
|
a b c d
|
|
8 NULL 9 NULL
|
|
8 NULL 10 NULL
|
|
DROP TABLE t1;
|
|
#
|
|
# MDEV-9457: Poor query plan chosen for ORDER BY query by a recent 10.1
|
|
#
|
|
create table t0 (a int);
|
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
|
create table t1 (
|
|
pk int primary key,
|
|
key1 int,
|
|
key2 int,
|
|
col1 char(255),
|
|
key(key1),
|
|
key(key2)
|
|
) engine=innodb;
|
|
set @a=-1;
|
|
insert into t1
|
|
select
|
|
@a:=@a+1,
|
|
@a,
|
|
@a,
|
|
repeat('abcd', 63)
|
|
from t0 A, t0 B, t0 C, t0 D;
|
|
# The following must NOT use 'index' on PK.
|
|
# It should use index_merge(key1,key2) + filesort
|
|
explain
|
|
select *
|
|
from t1
|
|
where key1<3 or key2<3
|
|
order by pk;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL # Using sort_union(key1,key2); Using where; Using filesort
|
|
explain
|
|
select *
|
|
from t1
|
|
where key1<3 or key2<3;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL # Using sort_union(key1,key2); Using where
|
|
drop table t0, t1;
|
|
#
|
|
# MDEV-18094: Query with order by limit picking index scan over filesort
|
|
#
|
|
create table t0 (a int);
|
|
INSERT INTO t0 VALUES (0),(0),(0),(0),(2),(0),(0),(1),(1),(0);
|
|
CREATE TABLE t1 (
|
|
a int(11),
|
|
b int(11),
|
|
c int(11),
|
|
KEY a_c (a,c),
|
|
KEY a_b (a,b)
|
|
) ENGINE=InnoDB;
|
|
insert into t1 select A.a , B.a, C.a from t0 A, t0 B, t0 C;
|
|
# should use ref access
|
|
explain select a,b,c from t1 where a=1 and c=2 order by b;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 SIMPLE t1 ref a_c,a_b a_c 10 const,const 20 Using where; Using filesort
|
|
# both should use range access
|
|
explain select a,b,c from t1 where a=1 and c=2 order by b limit 1000;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 SIMPLE t1 range a_c,a_b a_b 5 NULL 200 Using where
|
|
explain select a,b,c from t1 where a=1 and c=2 order by b limit 2000;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 SIMPLE t1 range a_c,a_b a_b 5 NULL 200 Using where
|
|
drop table t1,t0;
|
|
# Start of 10.2 tests
|
|
#
|
|
# MDEV-14071: wrong results with orderby_uses_equalities=on
|
|
# (duplicate of MDEV-13994)
|
|
#
|
|
CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB;
|
|
CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB;
|
|
CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB;
|
|
INSERT INTO t1 VALUES
|
|
(127,0,1),(188,0,1),(206,0,1),(218,0,1),(292,0,1),(338,0,1),(375,0,1),
|
|
(381,0,1),(409,0,1),(466,0,1),(469,0,1),(498,0,1),(656,0,1);
|
|
INSERT INTO t1 VALUES
|
|
(77,4,0),(86,7,0),(96,6,0),(96,7,0),(99,9,0),(99,10,0),(99,11,0),(104,4,0),
|
|
(106,5,0),(148,6,0),(177,6,0),(181,5,0),(188,8,0),(218,8,0),(253,7,0),
|
|
(268,4,0),(338,4,0),(409,7,0),(466,8,0),(469,8,0),(498,8,0),(656,8,0);
|
|
INSERT INTO t2 VALUES
|
|
(127,7),(188,8),(188,9),(206,6),(218,8),(218,9),(292,7),(338,4),(338,5),
|
|
(375,6),(381,5),(409,7),(409,8),(466,8),(466,9),(469,8),(469,9),(498,8),
|
|
(498,9),(656,8),(656,9);
|
|
INSERT INTO t3 VALUES
|
|
(4,'four'),(5,'five'),(6,'six'),(7,'seven'),(8,'eight'),(9,'nine');
|
|
SET @save_optimizer_switch=@@optimizer_switch;
|
|
SET optimizer_switch='orderby_uses_equalities=off';
|
|
SELECT i,n
|
|
FROM t1 INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
|
|
WHERE i IN (SELECT i FROM t1 WHERE z=1) AND z=0 ORDER BY i;
|
|
i n
|
|
188 eight
|
|
218 eight
|
|
338 four
|
|
409 seven
|
|
466 eight
|
|
469 eight
|
|
498 eight
|
|
656 eight
|
|
SELECT i,n
|
|
FROM t1 x INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
|
|
WHERE EXISTS (SELECT * FROM t1 WHERE i=x.i AND z=1) AND z=0 ORDER BY i;
|
|
i n
|
|
188 eight
|
|
218 eight
|
|
338 four
|
|
409 seven
|
|
466 eight
|
|
469 eight
|
|
498 eight
|
|
656 eight
|
|
SET optimizer_switch='orderby_uses_equalities=on';
|
|
SELECT i,n
|
|
FROM t1 INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
|
|
WHERE i IN (SELECT i FROM t1 WHERE z=1) AND z=0 ORDER BY i;
|
|
i n
|
|
188 eight
|
|
218 eight
|
|
338 four
|
|
409 seven
|
|
466 eight
|
|
469 eight
|
|
498 eight
|
|
656 eight
|
|
SELECT i,n
|
|
FROM t1 x INNER JOIN t2 USING (i,j) LEFT JOIN t3 USING (j)
|
|
WHERE EXISTS (SELECT * FROM t1 WHERE i=x.i AND z=1) AND z=0 ORDER BY i;
|
|
i n
|
|
188 eight
|
|
218 eight
|
|
338 four
|
|
409 seven
|
|
466 eight
|
|
469 eight
|
|
498 eight
|
|
656 eight
|
|
set optimizer_switch= @save_optimizer_switch;
|
|
DROP TABLE t1,t2,t3;
|
|
#
|
|
# MDEV-25858: Query results are incorrect when indexes are added
|
|
#
|
|
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb;
|
|
insert into t1 values (1),(2),(3);
|
|
CREATE TABLE t2 (
|
|
id int NOT NULL PRIMARY KEY,
|
|
id2 int NOT NULL,
|
|
d1 datetime,
|
|
d2 timestamp NOT NULL,
|
|
KEY id2 (id2)
|
|
) engine=innodb;
|
|
insert into t2 values
|
|
(1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
|
|
(2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
|
|
(3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00');
|
|
select
|
|
t1.id,t2.id
|
|
from
|
|
t1 left join
|
|
t2 on t2.id2 = t1.id and
|
|
t2.id = (select dd.id
|
|
from t2 dd
|
|
where
|
|
dd.id2 = t1.id and
|
|
d1 > '2019-02-06 00:00:00'
|
|
order by
|
|
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
|
|
);
|
|
id id
|
|
1 NULL
|
|
2 1
|
|
3 3
|
|
create index for_latest_sort on t2 (d1, d2, id);
|
|
select
|
|
t1.id,t2.id
|
|
from
|
|
t1 left join
|
|
t2 on t2.id2 = t1.id and
|
|
t2.id = (select dd.id
|
|
from t2 dd
|
|
where
|
|
dd.id2 = t1.id and
|
|
d1 > '2019-02-06 00:00:00'
|
|
order by
|
|
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
|
|
);
|
|
id id
|
|
1 NULL
|
|
2 1
|
|
3 3
|
|
# Now, same as above but use a DESC index
|
|
CREATE TABLE t3 (
|
|
id int NOT NULL PRIMARY KEY,
|
|
id2 int NOT NULL,
|
|
d1 datetime,
|
|
d2 timestamp NOT NULL,
|
|
KEY id2 (id2)
|
|
) engine=innodb;
|
|
insert into t3 values
|
|
(1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
|
|
(2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
|
|
(3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00');
|
|
create index for_latest_sort on t3 (d1 desc, d2 desc, id desc);
|
|
select
|
|
t1.id,t3.id
|
|
from
|
|
t1 left join
|
|
t3 on t3.id2 = t1.id and
|
|
t3.id = (select dd.id
|
|
from t3 dd
|
|
where
|
|
dd.id2 = t1.id and
|
|
d1 > '2019-02-06 00:00:00'
|
|
order by
|
|
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
|
|
);
|
|
id id
|
|
1 NULL
|
|
2 1
|
|
3 3
|
|
#
|
|
# MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT
|
|
#
|
|
# This must NOT have "Range checked for each record" without any
|
|
# provisions to produce rows in the required ordering:
|
|
explain
|
|
select
|
|
t1.id,t2.id
|
|
from
|
|
t1 left join
|
|
t2 on t2.id2 = t1.id and
|
|
t2.id = (select dd.id
|
|
from t2 dd
|
|
where
|
|
dd.id2 = t1.id and
|
|
d1 > '2019-02-06 00:00:00'
|
|
order by
|
|
dd.d1, dd.d2, dd.id limit 1
|
|
);
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index
|
|
1 PRIMARY t2 eq_ref PRIMARY,id2 PRIMARY 4 func # Using where
|
|
2 DEPENDENT SUBQUERY dd range id2,for_latest_sort for_latest_sort 6 NULL # Using where
|
|
drop table t1,t2,t3;
|
|
# End of 10.2 tests
|
|
#
|
|
# MDEV-26938 Support descending indexes internally in InnoDB
|
|
#
|
|
create table t1 (a int, b int, c int, key r (a desc, b asc));
|
|
insert t1 select seq % 10, seq div 10, seq from seq_1_to_55;
|
|
insert t1 values (NULL, NULL, NULL), (9, NULL, NULL);
|
|
explain select * from t1 force index(r) order by a,b limit 20;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 57 Using filesort
|
|
explain select * from t1 force index(r) order by a desc,b limit 20;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 SIMPLE t1 index NULL r 10 NULL 20
|
|
select * from t1 force index(r) order by a desc,b limit 20;
|
|
a b c
|
|
9 NULL NULL
|
|
9 0 9
|
|
9 1 19
|
|
9 2 29
|
|
9 3 39
|
|
9 4 49
|
|
8 0 8
|
|
8 1 18
|
|
8 2 28
|
|
8 3 38
|
|
8 4 48
|
|
7 0 7
|
|
7 1 17
|
|
7 2 27
|
|
7 3 37
|
|
7 4 47
|
|
6 0 6
|
|
6 1 16
|
|
6 2 26
|
|
6 3 36
|
|
drop table t1;
|