polardbxengine/mysql-test/t/order_by_limit.test

235 lines
5.1 KiB
Plaintext

--echo #
--echo # WL#6986 : Make switching of index due to order by limit cost based
--echo #
--echo # Testcase for Bug#16522053
CREATE TABLE t1 (
pk INT PRIMARY KEY AUTO_INCREMENT,
i INT,
j INT,
INDEX (i),
INDEX (j)
);
INSERT INTO t1 (i,j) VALUES (1,1);
let $1=7;
set @d=1;
while ($1)
{
eval INSERT INTO t1 (i,j) SELECT i+@d, j+@d from t1;
eval set @d=@d*2;
dec $1;
}
ANALYZE TABLE t1;
let $query= SELECT * FROM t1
WHERE i<100 AND j<10
ORDER BY i LIMIT 5;
eval EXPLAIN $query;
eval $query;
DROP TABLE t1;
CREATE TABLE t0 (
i0 INTEGER NOT NULL
);
INSERT INTO t0 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
CREATE TABLE t1 (
pk INTEGER PRIMARY KEY,
i1 INTEGER NOT NULL,
i2 INTEGER NOT NULL,
INDEX k1 (i1),
INDEX k2 (i1,i2)
) ENGINE=InnoDB;
INSERT INTO t1
SELECT a0.i0 + 10*a1.i0 + 100*a0.i0 + 1000*a1.i0,
(a0.i0 + 10*a1.i0 + 100*a0.i0 + 1000*a1.i0) % 1000,
(a0.i0 + 10*a1.i0 + 100*a0.i0 + 1000*a1.i0) % 1000
FROM t0 AS a0, t0 AS a1;
CREATE TABLE t2 (
pk INTEGER PRIMARY KEY,
i1 INTEGER NOT NULL,
INDEX k1 (i1)
) ENGINE=InnoDB;
INSERT INTO t2
SELECT a0.i0 + 10*a1.i0 + 100*a0.i0 + 1000*a1.i0,
(a0.i0 + 10*a1.i0 + 100*a0.i0 + 1000*a1.i0) % 500
FROM t0 AS a0, t0 AS a1;
ANALYZE TABLE t1,t2;
--echo # Query should use index to optimize the ORDER BY LIMIT
let query=
SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1
WHERE t1.pk > 7000 and t1.i1 > 2
ORDER BY t1.i1 LIMIT 2;
eval EXPLAIN $query;
--echo # Query should not make the switch to use index to
--echo # optimize ORDER BY LIMIT. So should be using filesort
let query=
SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1
WHERE t1.pk > 7000 and t1.i1 > 2
ORDER BY t1.i1 LIMIT 5;
eval EXPLAIN $query;
eval $query;
--echo # Changing range condition on i1 should make
--echo # key on i1 get picked to give the order
let query=
SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1
WHERE t1.pk > 7000 and t1.i1 > 800
ORDER BY t1.i1 LIMIT 5;
eval EXPLAIN $query;
eval $query;
--echo # Use range condition only on pk to see if switch
--echo # happens just for ORDER BY LIMIT
--echo # Should not happen unless range results in too
--echo # many records
let query=
SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1
WHERE t1.pk > 7000 ORDER BY t1.i1 LIMIT 5;
eval EXPLAIN $query;
eval $query;
let query=
SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1
WHERE t1.pk > 1000 ORDER BY t1.i1 LIMIT 5;
eval EXPLAIN $query;
eval $query;
--echo # check if switch happens when the index for order
--echo # by is non-covering
let query=
SELECT t1.i1,t1.i2 FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1
WHERE t1.pk > 100 ORDER BY t1.i1 LIMIT 5;
eval EXPLAIN $query;
eval $query;
--echo # Reduce the fanout for table t2 and check
--echo # that index for order by is not choosen
let query=
SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1
WHERE t1.pk > 7000 and t2.pk = 100 ORDER BY t1.i1 LIMIT 5;
eval EXPLAIN $query;
eval $query;
--echo # Increase the fanout to see if index gets choosen
--echo # for order by for which range scan was choosen
--echo # earlier
INSERT INTO t2
SELECT a0.i0 + 10*a1.i0 + 100*a0.i0 + 1000*a1.i0 + 1,
(a0.i0 + 10*a1.i0 + 100*a0.i0 + 1000*a1.i0) % 500
FROM t0 AS a0, t0 AS a1;
ANALYZE TABLE t2;
let query=
SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1
WHERE t1.pk > 7000 ORDER BY t1.i1 LIMIT 5;
eval EXPLAIN $query;
eval $query;
--echo # Check if the index for order by is used when
--echo # force index is done on order by
let query=
SELECT * FROM t1 FORCE INDEX FOR ORDER BY (k2) STRAIGHT_JOIN t2 ON
t1.i1=t2.i1 WHERE t1.pk > 7000 ORDER BY t1.i1 LIMIT 5;
eval EXPLAIN $query;
eval $query;
DROP TABLE t0, t1, t2;
--echo #
--echo # Bug #26483909: INCORRECT BEHAVIOR FOR QUERY WITH DISTINCT
--echo # and ORDER BY ... LIMIT.
--echo #
CREATE TABLE t1 (
pk int(11) NOT NULL,
col_int int(11),
col_varchar_key varchar(20),
PRIMARY KEY (pk),
KEY col_varchar_key (col_varchar_key),
KEY col_varchar_key_2 (col_varchar_key(5))
);
INSERT INTO t1 VALUES (1,2,'t'), (2,5,'efqsdksj'),
(3,NULL,'fqsdksjijcs'),(4,8,'qsdksjijc'),
(5,40,NULL),(6,3,'sdksji'),(7,2,NULL),
(8,3,'dks'),(9,0,'ksjijcsz'),
(10,84,'sjijcszxwbjj');
let query1=
SELECT DISTINCT col_int
FROM t1
WHERE col_varchar_key <> 'c'
OR col_varchar_key > 'w'
ORDER BY col_varchar_key
LIMIT 100;
ANALYZE TABLE t1;
SET @@SESSION.sql_mode='NO_ENGINE_SUBSTITUTION';
eval EXPLAIN $query1;
eval $query1;
DROP TABLE t1;
--echo #
--echo # Bug#29487181 INCORRECT 'ROWS' AND 'FILTERED' ESTIMATE IN
--echo # 'ORDER BY ... LIMIT .' QUERIES
--echo #
CREATE TABLE t1 (
col_int_unique INT DEFAULT NULL,
col_int_key INT DEFAULT NULL,
UNIQUE KEY col_int_unique (col_int_unique),
KEY col_int_key (col_int_key)
);
INSERT INTO t1 VALUES (49,49), (9,7), (0,1), (2,42);
CREATE TABLE t2 (
col_int_unique INT DEFAULT NULL,
pk INT NOT NULL,
PRIMARY KEY (pk),
UNIQUE KEY col_int_unique (col_int_unique)
);
INSERT INTO t2 VALUES (2,8), (5,2), (6,1);
ANALYZE TABLE t1,t2;
EXPLAIN
SELECT STRAIGHT_JOIN t1.col_int_key AS field1
FROM t1 JOIN t2
ON t2.pk = t1.col_int_unique OR
t2.col_int_unique = t1.col_int_key
ORDER BY field1 LIMIT 2;
DROP TABLE t1,t2;