Current Path : /home/usr.opt/mysql57/mysql-test/r/ |
FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64 |
Current File : /home/usr.opt/mysql57/mysql-test/r/order_by_limit.result |
# # WL#6986 : Make switching of index due to order by limit cost based # # 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); set @d=1; INSERT INTO t1 (i,j) SELECT i+@d, j+@d from t1; set @d=@d*2; INSERT INTO t1 (i,j) SELECT i+@d, j+@d from t1; set @d=@d*2; INSERT INTO t1 (i,j) SELECT i+@d, j+@d from t1; set @d=@d*2; INSERT INTO t1 (i,j) SELECT i+@d, j+@d from t1; set @d=@d*2; INSERT INTO t1 (i,j) SELECT i+@d, j+@d from t1; set @d=@d*2; INSERT INTO t1 (i,j) SELECT i+@d, j+@d from t1; set @d=@d*2; INSERT INTO t1 (i,j) SELECT i+@d, j+@d from t1; set @d=@d*2; ANALYZE TABLE t1; Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE i<100 AND j<10 ORDER BY i LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL range i,j j 5 NULL 9 77.34 Using index condition; Using where; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i` AS `i`,`test`.`t1`.`j` AS `j` from `test`.`t1` where ((`test`.`t1`.`i` < 100) and (`test`.`t1`.`j` < 10)) order by `test`.`t1`.`i` limit 5 SELECT * FROM t1 WHERE i<100 AND j<10 ORDER BY i LIMIT 5; pk i j 1 1 1 2 2 2 3 3 3 4 4 4 6 5 5 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; Table Op Msg_type Msg_text test.t1 analyze status OK test.t2 analyze status OK # Query should use index to optimize the ORDER BY LIMIT EXPLAIN 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; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL index PRIMARY,k1,k2 k1 4 NULL 6 29.70 Using where 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 7000) and (`test`.`t1`.`i1` > 2)) order by `test`.`t1`.`i1` limit 2 # Query should not make the switch to use index to # optimize ORDER BY LIMIT. So should be using filesort EXPLAIN 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; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL range PRIMARY,k1,k2 PRIMARY 4 NULL 30 99.00 Using where; Using filesort 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 7000) and (`test`.`t1`.`i1` > 2)) order by `test`.`t1`.`i1` limit 5 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; pk i1 i2 pk i1 7070 70 70 7070 70 8080 80 80 8080 80 9090 90 90 9090 90 7171 171 171 7171 171 8181 181 181 8181 181 # Changing range condition on i1 should make # key on i1 get picked to give the order EXPLAIN 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; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL range PRIMARY,k1,k2 k2 4 NULL 20 30.00 Using where; Using index 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 7000) and (`test`.`t1`.`i1` > 800)) order by `test`.`t1`.`i1` limit 5 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; pk i1 i2 pk i1 # Use range condition only on pk to see if switch # happens just for ORDER BY LIMIT # Should not happen unless range results in too # many records EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1 WHERE t1.pk > 7000 ORDER BY t1.i1 LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL range PRIMARY,k1,k2 PRIMARY 4 NULL 30 100.00 Using where; Using filesort 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 7000)) order by `test`.`t1`.`i1` limit 5 SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1 WHERE t1.pk > 7000 ORDER BY t1.i1 LIMIT 5; pk i1 i2 pk i1 7070 70 70 7070 70 8080 80 80 8080 80 9090 90 90 9090 90 7171 171 171 7171 171 8181 181 181 8181 181 EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1 WHERE t1.pk > 1000 ORDER BY t1.i1 LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL index PRIMARY,k1,k2 k1 4 NULL 5 90.00 Using where 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 1000)) order by `test`.`t1`.`i1` limit 5 SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1 WHERE t1.pk > 1000 ORDER BY t1.i1 LIMIT 5; pk i1 i2 pk i1 1010 10 10 1010 10 2020 20 20 2020 20 3030 30 30 3030 30 4040 40 40 4040 40 5050 50 50 5050 50 # check if switch happens when the index for order # by is non-covering EXPLAIN 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; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL index PRIMARY,k1,k2 k1 4 NULL 5 99.00 Using where 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 100)) order by `test`.`t1`.`i1` limit 5 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; i1 i2 10 10 20 20 30 30 40 40 50 50 # Reduce the fanout for table t2 and check # that index for order by is not choosen EXPLAIN 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; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL range PRIMARY,k1,k2 PRIMARY 4 NULL 30 100.00 Using where; Using filesort 1 SIMPLE t2 NULL const PRIMARY,k1 PRIMARY 4 const 1 5.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t2`.`pk` = 100) and (`test`.`t1`.`pk` > 7000)) order by `test`.`t1`.`i1` limit 5 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; pk i1 i2 pk i1 # Increase the fanout to see if index gets choosen # for order by for which range scan was choosen # 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; Table Op Msg_type Msg_text test.t2 analyze status OK EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1 WHERE t1.pk > 7000 ORDER BY t1.i1 LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL index PRIMARY,k1,k2 k1 4 NULL 6 30.00 Using where 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 7000)) order by `test`.`t1`.`i1` limit 5 SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1 WHERE t1.pk > 7000 ORDER BY t1.i1 LIMIT 5; pk i1 i2 pk i1 7070 70 70 7070 70 7070 70 70 7071 70 8080 80 80 8080 80 8080 80 80 8081 80 9090 90 90 9090 90 # Check if the index for order by is used when # force index is done on order by EXPLAIN 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; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL index PRIMARY,k1,k2 k2 8 NULL 6 30.00 Using where; Using index 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` FORCE INDEX FOR ORDER BY (`k2`) straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 7000)) order by `test`.`t1`.`i1` limit 5 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; pk i1 i2 pk i1 7070 70 70 7070 70 7070 70 70 7071 70 8080 80 80 8080 80 8080 80 80 8081 80 9090 90 90 9090 90 DROP TABLE t0, t1, t2; # # Bug 31686878 - BACKPORT MAIN BUG 30348211 TO RELEASE 5.7 # CREATE TABLE t (id BIGINT NOT NULL, other_id BIGINT NOT NULL, covered_column VARCHAR(50) NOT NULL, non_covered_column VARCHAR(50) NOT NULL, PRIMARY KEY (id), INDEX index_other_id_covered_column (other_id, covered_column)); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (10, 10, '10', '10'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (9, 9, '9', '9'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (8, 8, '8', '8'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (7, 7, '7', '7'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (6, 6, '6', '6'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (5, 5, '5', '5'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (4, 4, '4', '4'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (3, 3, '3', '3'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (2, 2, '2', '2'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (1, 1, '1', '1'); SET optimizer_trace = "enabled=on", optimizer_trace_max_mem_size = 1000000, end_markers_in_json = ON; SET optimizer_switch = "prefer_ordering_index=on"; ANALYZE TABLE t; Table Op Msg_type Msg_text test.t analyze status OK EXPLAIN SELECT non_covered_column FROM t WHERE other_id > 3 ORDER BY id ASC LIMIT 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL index index_other_id_covered_column PRIMARY 8 NULL 2 70.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` where (`test`.`t`.`other_id` > 3) order by `test`.`t`.`id` limit 2 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; should_be_1 1 SET optimizer_switch = "prefer_ordering_index=off"; EXPLAIN SELECT non_covered_column FROM t WHERE other_id > 3 ORDER BY id ASC LIMIT 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL range index_other_id_covered_column index_other_id_covered_column 8 NULL 7 100.00 Using index condition; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` where (`test`.`t`.`other_id` > 3) order by `test`.`t`.`id` limit 2 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_0 FROM information_schema.optimizer_trace; should_be_0 0 SET optimizer_switch = default; EXPLAIN SELECT non_covered_column FROM t WHERE other_id > 3 ORDER BY id ASC LIMIT 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL index index_other_id_covered_column PRIMARY 8 NULL 2 70.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` where (`test`.`t`.`other_id` > 3) order by `test`.`t`.`id` limit 2 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; should_be_1 1 SET optimizer_switch = "prefer_ordering_index=on"; EXPLAIN SELECT non_covered_column FROM t FORCE INDEX(PRIMARY) WHERE other_id > 3 ORDER BY id ASC LIMIT 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL index NULL PRIMARY 8 NULL 2 33.33 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` FORCE INDEX (PRIMARY) where (`test`.`t`.`other_id` > 3) order by `test`.`t`.`id` limit 2 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; should_be_1 1 SET optimizer_switch = "prefer_ordering_index=off"; EXPLAIN SELECT non_covered_column FROM t FORCE INDEX(PRIMARY) WHERE other_id > 3 ORDER BY id ASC LIMIT 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL index NULL PRIMARY 8 NULL 2 33.33 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` FORCE INDEX (PRIMARY) where (`test`.`t`.`other_id` > 3) order by `test`.`t`.`id` limit 2 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; should_be_1 1 INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (10+1+10, 10, '10', '10'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (9+1+10, 9, '9', '9'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (8+1+10, 8, '8', '8'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (7+1+10, 7, '7', '7'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (6+1+10, 6, '6', '6'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (5+1+10, 5, '5', '5'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (4+1+10, 4, '4', '4'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (3+1+10, 3, '3', '3'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (2+1+10, 2, '2', '2'); INSERT INTO t (id, other_id, covered_column, non_covered_column) VALUES (1+1+10, 1, '1', '1'); SET optimizer_switch = "prefer_ordering_index=on"; ANALYZE TABLE t; Table Op Msg_type Msg_text test.t analyze status OK EXPLAIN SELECT non_covered_column FROM t WHERE id > 8 GROUP BY other_id LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL index PRIMARY,index_other_id_covered_column index_other_id_covered_column 60 NULL 3 60.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` where (`test`.`t`.`id` > 8) group by `test`.`t`.`other_id` limit 1 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; should_be_1 1 SET optimizer_switch = "prefer_ordering_index=off"; SELECT (trace LIKE '%"plan_changed": true%') AS should_be_0 FROM information_schema.optimizer_trace; should_be_0 0 SET optimizer_switch = default; EXPLAIN SELECT non_covered_column FROM t WHERE id > 8 GROUP BY other_id LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL index PRIMARY,index_other_id_covered_column index_other_id_covered_column 60 NULL 3 60.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` where (`test`.`t`.`id` > 8) group by `test`.`t`.`other_id` limit 1 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; should_be_1 1 SET optimizer_switch = "prefer_ordering_index=on"; EXPLAIN SELECT non_covered_column FROM t FORCE INDEX FOR GROUP BY (index_other_id_covered_column) WHERE id > 8 GROUP BY other_id LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL index PRIMARY,index_other_id_covered_column index_other_id_covered_column 60 NULL 3 60.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` FORCE INDEX FOR GROUP BY (`index_other_id_covered_column`) where (`test`.`t`.`id` > 8) group by `test`.`t`.`other_id` limit 1 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; should_be_1 1 SET optimizer_switch = "prefer_ordering_index=off"; EXPLAIN SELECT non_covered_column FROM t FORCE INDEX FOR GROUP BY (index_other_id_covered_column) WHERE id > 8 GROUP BY other_id LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t NULL index PRIMARY,index_other_id_covered_column index_other_id_covered_column 60 NULL 3 60.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` FORCE INDEX FOR GROUP BY (`index_other_id_covered_column`) where (`test`.`t`.`id` > 8) group by `test`.`t`.`other_id` limit 1 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; should_be_1 1 DROP TABLE t;