mariadb/mysql-test/main/partition_index_scan.test

554 lines
16 KiB
Text

--source include/have_partition.inc
--source include/have_sequence.inc
--source include/no_view_protocol.inc
--disable_ps2_protocol
--echo # Index scans with PARTITION BY RANGE
if ($MTR_COMBINATION_ASC)
{
let $direction=;
let $opposite_direction=desc;
}
if ($MTR_COMBINATION_DESC)
{
let $direction=desc;
let $opposite_direction=;
}
eval
CREATE TABLE t1 (
c int,
INDEX idx1(c $direction)
) PARTITION BY RANGE COLUMNS(c) (
PARTITION `p1` VALUES LESS THAN (10),
PARTITION `p2` VALUES LESS THAN (20),
PARTITION `p3` VALUES LESS THAN (30),
PARTITION `p4` VALUES LESS THAN (40),
PARTITION `p5` VALUES LESS THAN MAXVALUE
);
insert into t1 select seq from seq_1_to_50;
--echo ## Case 1: unordered scan with ha_partition::index_first/index_last
flush status;
select * from t1 ORDER BY c LIMIT 1;
show status like 'handler_read_%';
flush status;
select * from t1 ORDER BY c LIMIT 2;
show status like 'handler_read_%';
flush status;
select * from t1 ORDER BY c LIMIT 16;
show status like 'handler_read_%';
--echo ### select * from t1 ORDER BY c LIMIT 2
let $out=`analyze format=json select * from t1 ORDER BY c LIMIT 2`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 ORDER BY c DESC LIMIT 1;
show status like 'handler_read_%';
flush status;
select * from t1 ORDER BY c DESC LIMIT 2;
show status like 'handler_read_%';
flush status;
select * from t1 ORDER BY c DESC LIMIT 16;
show status like 'handler_read_%';
--echo ### select * from t1 ORDER BY c DESC LIMIT 2
let $out=`analyze format=json select * from t1 ORDER BY c DESC LIMIT 2`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
--echo ## Case 1: Unordered scans with MRR
flush status;
select * from t1 where c between 25 and 35 order by c limit 7;
show status like 'handler_read_%';
--echo ### select * from t1 where c between 25 and 35 order by c limit 7
let $out=`analyze format=json select * from t1 where c between 25 and 35 order by c limit 7`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 where c between 25 and 35 order by c desc limit 7;
show status like 'handler_read_%';
--echo ### select * from t1 where c between 25 and 35 order by c desc limit 7
let $out=`analyze format=json select * from t1 where c between 25 and 35 order by c limit 7`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
drop table t1;
--echo ## Case 1: multiple range columns, keys having the same direction
eval
CREATE TABLE t1 (
c int,
d INT,
INDEX idx1(c $direction, d $direction)
) PARTITION BY RANGE COLUMNS(c, d) (
PARTITION `p1` VALUES LESS THAN (1, 1),
PARTITION `p2` VALUES LESS THAN (2, 2),
PARTITION `p3` VALUES LESS THAN (3, 3),
PARTITION `p4` VALUES LESS THAN (4, 4),
PARTITION `p5` VALUES LESS THAN (MAXVALUE, MAXVALUE)
);
insert into t1 select t2.seq, t3.seq from seq_1_to_5 t2, seq_1_to_5 t3;
flush status;
select * from t1 order by c, d limit 16;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 order by c, d limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 order by c desc, d desc limit 16;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 order by c desc, d desc limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 order by c desc, d limit 16;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 order by c desc, d limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 order by c, d desc limit 16;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 order by c, d desc limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
drop table t1;
--echo ## Case 1: multiple range columns, keys having opposite directions
eval
CREATE TABLE t1 (
c int,
d INT,
INDEX idx1(c $direction, d $opposite_direction)
) PARTITION BY RANGE COLUMNS(c, d) (
PARTITION `p1` VALUES LESS THAN (1, 1),
PARTITION `p2` VALUES LESS THAN (2, 2),
PARTITION `p3` VALUES LESS THAN (3, 3),
PARTITION `p4` VALUES LESS THAN (4, 4),
PARTITION `p5` VALUES LESS THAN (MAXVALUE, MAXVALUE)
);
insert into t1 select t2.seq, t3.seq from seq_1_to_5 t2, seq_1_to_5 t3;
flush status;
select * from t1 order by c, d limit 16;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 order by c, d limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 order by c desc, d desc limit 16;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 order by c desc, d desc limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 order by c desc, d limit 16;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 order by c desc, d limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 order by c, d desc limit 16;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 order by c, d desc limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
drop table t1;
eval
CREATE TABLE t1 (
c int,
d INT,
INDEX idx1(c $direction, d)
) PARTITION BY RANGE COLUMNS(c) (
PARTITION `p1` VALUES LESS THAN (10),
PARTITION `p2` VALUES LESS THAN (20),
PARTITION `p3` VALUES LESS THAN (30),
PARTITION `p4` VALUES LESS THAN (40),
PARTITION `p5` VALUES LESS THAN MAXVALUE
);
insert into t1 select t2.seq, t3.seq from seq_1_to_50 t2, seq_100_to_200 t3;
--echo ## Case 1: unordered scan with ha_partition::index_first
flush status;
select * from t1 where d = 113 ORDER BY d LIMIT 1;
show status like 'handler_read_%';
let $out=`analyze format=json select * from t1 where d = 113 ORDER BY d LIMIT 1`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
drop table t1;
--echo ## Case 1: calls to ha_partition::read_range_first and
--echo ## ha_partition::index_read_map, via loose index scan.
--echo ## No read_prev
eval
CREATE TABLE t1 (
a INT,
b INT,
KEY ( a $direction, b )
) PARTITION BY RANGE COLUMNS(a) (
PARTITION `p1` VALUES LESS THAN (10),
PARTITION `p2` VALUES LESS THAN (20),
PARTITION `p3` VALUES LESS THAN (30),
PARTITION `p4` VALUES LESS THAN (40),
PARTITION `p5` VALUES LESS THAN MAXVALUE
);
insert into t1 select seq, seq from seq_1_to_50;
FLUSH status;
SELECT a, MIN(b) FROM t1 WHERE a > 18 and a < 21 GROUP BY a;
show status like 'handler_read_%';
FLUSH status;
SELECT a, MIN(b) FROM t1 WHERE a > 16 and a < 25 GROUP BY a;
show status like 'handler_read_%';
let $out=`analyze format=json SELECT a, MIN(b) FROM t1 WHERE a > 18 and a < 21 GROUP BY a`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
FLUSH status;
SELECT a, MAX(b) FROM t1 WHERE a > 18 and a < 21 GROUP BY a;
show status like 'handler_read_%';
FLUSH status;
SELECT a, MAX(b) FROM t1 WHERE a > 16 and a < 25 GROUP BY a;
show status like 'handler_read_%';
let $out=`analyze format=json SELECT a, MAX(b) FROM t1 WHERE a > 18 and a < 21 GROUP BY a`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
DROP TABLE t1;
--echo ## Case 2: calls to ha_partition::read_range_first and
--echo ## ha_partition::index_read_map, via loose index scan
eval
CREATE TABLE t1 (
a INT,
b INT,
KEY ( a, b $direction)
) PARTITION BY RANGE COLUMNS(b) (
PARTITION `p1` VALUES LESS THAN (10),
PARTITION `p2` VALUES LESS THAN (20),
PARTITION `p3` VALUES LESS THAN (30),
PARTITION `p4` VALUES LESS THAN (40),
PARTITION `p5` VALUES LESS THAN MAXVALUE
);
insert into t1 select seq, seq from seq_1_to_50;
FLUSH status;
SELECT a, MIN(b) FROM t1 WHERE a = 20 GROUP BY a;
show status like 'handler_read_%';
let $out=`analyze format=json SELECT a, MIN(b) FROM t1 WHERE a = 20 GROUP BY a`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
DROP TABLE t1;
eval
CREATE TABLE t1 (
c int,
d INT,
INDEX idx1(c, d $direction)
) PARTITION BY RANGE COLUMNS(d) (
PARTITION `p1` VALUES LESS THAN (10),
PARTITION `p2` VALUES LESS THAN (20),
PARTITION `p3` VALUES LESS THAN (30),
PARTITION `p4` VALUES LESS THAN (40),
PARTITION `p5` VALUES LESS THAN MAXVALUE
);
insert into t1 select t2.seq, t3.seq from seq_100_to_200 t2, seq_1_to_50 t3;
--echo ## Case 2: Unordered scans with MRR
flush status;
select * from t1 where c=113 and d between 25 and 35 order by d limit 3;
show status like 'handler_read_%';
--echo ### select * from t1 where c=113 and d between 25 and 35 order by d limit 3
let $out=`analyze format=json select * from t1 where c=113 and d between 25 and 35 order by d limit 3`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
--echo ## Case 2: Unordered scans in ha_partition::index_read_map
flush status;
select * from t1 where c = 120 ORDER BY d DESC LIMIT 1;
show status like 'handler_read_%';
flush status;
select * from t1 where c = 120 ORDER BY d DESC LIMIT 2;
show status like 'handler_read_%';
flush status;
select * from t1 where c = 120 ORDER BY d DESC LIMIT 16;
show status like 'handler_read_%';
--echo ### select * from t1 where c = 120 ORDER BY d DESC LIMIT 2
let $out=`analyze format=json select * from t1 where c = 120 ORDER BY d DESC LIMIT 2`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
flush status;
select * from t1 where c = 120 ORDER BY d LIMIT 1;
show status like 'handler_read_%';
flush status;
select * from t1 where c = 120 ORDER BY d LIMIT 2;
show status like 'handler_read_%';
flush status;
select * from t1 where c = 120 ORDER BY d LIMIT 16;
show status like 'handler_read_%';
select * from t1 where c = 120 LIMIT 2;
--echo ### select * from t1 where c = 120 ORDER BY d LIMIT 2
let $out=`analyze format=json select * from t1 where c = 120 ORDER BY d LIMIT 2`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
--echo ### When one partition has no results
delete from t1 where c = 120 and (d between 30 and 40 or d between 10 and 20);
flush status;
select * from t1 where c = 120 ORDER BY d DESC LIMIT 16;
show status like 'handler_read_%';
flush status;
select * from t1 where c = 120 ORDER BY d LIMIT 16;
show status like 'handler_read_%';
drop table t1;
eval
CREATE TABLE t1 (
c1 int, c2 int,
d INT,
INDEX idx1(c1, c2, d $direction)
) PARTITION BY RANGE COLUMNS(d) (
PARTITION `p1` VALUES LESS THAN (10),
PARTITION `p2` VALUES LESS THAN (20),
PARTITION `p3` VALUES LESS THAN (30),
PARTITION `p4` VALUES LESS THAN (40),
PARTITION `p5` VALUES LESS THAN MAXVALUE
);
insert into t1 select t2.seq, t2.seq, t3.seq from seq_100_to_200 t2, seq_1_to_50 t3;
--echo ## Case 2 with two prefix columns: Unordered scans in
--echo ## ha_partition::index_read_map
flush status;
select * from t1 where c1 = 120 and c2 = 120 ORDER BY d DESC LIMIT 16;
show status like 'handler_read_%';
--echo ### select * from t1 where c1 = 120 and c2 = 120 ORDER BY d DESC LIMIT 16
let $out=`analyze format=json select * from t1 where c1 = 120 and c2 = 120 ORDER BY d DESC LIMIT 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
drop table t1;
--echo ## PARTITION BY RANGE (expr)
eval
CREATE TABLE t1 (
c int,
d INT,
INDEX idx1(c, d $direction)
) PARTITION BY RANGE (d % 5) (
PARTITION `p1` VALUES LESS THAN (1),
PARTITION `p2` VALUES LESS THAN (2),
PARTITION `p3` VALUES LESS THAN (3),
PARTITION `p4` VALUES LESS THAN (4),
PARTITION `p5` VALUES LESS THAN MAXVALUE
);
insert into t1 select t2.seq, t3.seq from seq_100_to_200 t2, seq_1_to_50 t3;
flush status;
select * from t1 where c = 120 ORDER BY d DESC LIMIT 1;
show status like 'handler_read_%';
flush status;
select * from t1 where c = 120 ORDER BY d DESC LIMIT 2;
show status like 'handler_read_%';
flush status;
select * from t1 where c = 120 ORDER BY d LIMIT 2;
show status like 'handler_read_%';
flush status;
--echo ### Unordered scan (filesort + mrr)
select * from t1 where c = 120 ORDER BY d % 5 LIMIT 2;
show status like 'handler_read_%';
flush status;
select * from t1 where c = 120 LIMIT 2;
show status like 'handler_read_%';
--echo ### select * from t1 where c = 120 ORDER BY d LIMIT 2
let $out=`analyze format=json select * from t1 where c = 120 ORDER BY d LIMIT 2`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
--echo ### select * from t1 where c = 120 ORDER BY d % 5 LIMIT 2
let $out=`analyze format=json select * from t1 where c = 120 ORDER BY d % 5 LIMIT 2`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
drop table t1;
--echo ## Unordered scan (partition table is the second in the join
--echo ## order after optimization) extracted and minimised from the
--echo ## test main.partition
CREATE TABLE t1 (
id int(8),
PRIMARY KEY (id)
);
INSERT INTO t1 VALUES (11), (22), (33);
eval
CREATE TABLE t2 (
taken int,
id int,
PRIMARY KEY (id,taken $direction),
KEY taken (taken)
)
PARTITION BY RANGE (taken)
(
PARTITION p1 VALUES LESS THAN (50),
PARTITION p2 VALUES LESS THAN (60),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
INSERT INTO t2 VALUES
(51,11), /* p2 */
(63,11), /* p3 */
(51,22), /* p2 */
(53,22), /* p2 */
(55,22), /* p2 */
(57,22), /* p2 */
(61,22), /* p3 */
(63,22), /* p3 */
(51,33), /* p2 */
(55,33) /* p2 */
;
set @ff=53;
set @tt=64;
flush status;
SELECT t1.id
FROM t1
WHERE t1.id IN (
SELECT distinct id
FROM t2
WHERE taken BETWEEN @ff AND @tt)
ORDER BY t1.id;
show status like 'handler_read_%';
--echo ### same statement as above
let $out=`analyze format=json
SELECT t1.id
FROM t1
WHERE t1.id IN (
SELECT distinct id
FROM t2
WHERE taken BETWEEN @ff AND @tt)
ORDER BY t1.id`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
--echo ## ordered scan (partition table is the first in the join
--echo ## order after optimization and ORDER BY differs from
--echo ## PARTITION BY RANGE)
flush status;
SELECT t1.id
FROM t1
WHERE t1.id IN (
SELECT distinct id
FROM t2
WHERE taken BETWEEN 53 AND 64)
ORDER BY t1.id;
show status like 'handler_read_%';
--echo ### same statement as above
let $out=`analyze format=json
SELECT t1.id
FROM t1
WHERE t1.id IN (
SELECT distinct id
FROM t2
WHERE taken BETWEEN 53 AND 64)
ORDER BY t1.id`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
--echo ## ordered scan again (only one table and no ORDER BY)
flush status;
select distinct id from t2 where taken between @ff and @tt;
show status like 'handler_read_%';
--echo ### same statement as above
let $out=`analyze format=json
select distinct id from t2 where taken between @ff and @tt`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
drop table t1, t2;
--echo # partition index scan method is reset
CREATE TABLE t1 (
c int,
d INT,
filler varchar(100),
INDEX idx1(c , d )
) PARTITION BY RANGE COLUMNS(c, d) (
PARTITION `p1` VALUES LESS THAN (1, 1),
PARTITION `p2` VALUES LESS THAN (2, 2),
PARTITION `p3` VALUES LESS THAN (3, 3),
PARTITION `p4` VALUES LESS THAN (4, 4),
PARTITION `p5` VALUES LESS THAN (MAXVALUE, MAXVALUE)
);
insert into t1
select t2.seq, t3.seq, 'filler' from seq_1_to_5 t2, seq_1_to_5 t3;
flush status;
let $out=`analyze format=json select c,d from t1 order by d limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
let $out=`analyze format=json select c,d from t1 order by c,d limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
let $out=`analyze format=json select c,d from t1 order by d limit 16`;
evalp set @js='$out';
select json_extract(@js,'$**.partitions_index_scan_method');
drop table t1;
--enable_ps2_protocol