Bug #75510 | MySQL chooses index scan over full table scan | ||
---|---|---|---|
Submitted: | 15 Jan 2015 0:36 | Modified: | 16 Jan 2015 9:53 |
Reporter: | Justin Swanhart | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 5.6.21 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[15 Jan 2015 0:36]
Justin Swanhart
[15 Jan 2015 4:19]
Justin Swanhart
Note, that without an additional column, the example does a covering index scan, which is correct, so you need to do the following to observe the bug: alter table a add b int default 1; explain select a,b from a where a = 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: ref possible_keys: a key: a key_len: 5 ref: const rows: 549376 Extra: NULL 1 row in set (0.00 sec) So you can see it uses ref access instead of full table scan. Compare times: -- MySQL does not use index on a mysql> select a,b from a ignore index(a) where a = 1 ; ... 1048576 rows in set (1.05 sec) -- MySQL uses index on a mysql> select a,b from a where a = 1 ; ... 1048576 rows in set (1.93 sec) Here is the explain for the ignore index: mysql> explain select a,b from a ignore index(a) where a = 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1098752 Extra: Using where 1 row in set (0.00 sec)
[16 Jan 2015 9:53]
MySQL Verification Team
Hello Justin Swanhart, Thank you for the report and test case. Thanks, Umesh
[16 Jan 2015 9:55]
MySQL Verification Team
// 5.6.24 +-------------------------+---------------------------------------------------------+ | Variable_name | Value | +-------------------------+---------------------------------------------------------+ | innodb_version | 5.6.24 | | protocol_version | 10 | | slave_type_conversions | | | version | 5.6.24-enterprise-commercial-advanced | | version_comment | MySQL Enterprise Server - Advanced Edition (Commercial) | | version_compile_machine | x86_64 | | version_compile_os | linux-glibc2.5 | +-------------------------+---------------------------------------------------------+ 7 rows in set (0.00 sec) mysql> create table a(a int,key(a)) engine=innodb; Query OK, 0 rows affected (0.01 sec) mysql> insert into a values (1); Query OK, 1 row affected (0.01 sec) mysql> insert into a select * from a; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 8 rows affected (0.00 sec) Records: 8 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 16 rows affected (0.00 sec) Records: 16 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 32 rows affected (0.01 sec) Records: 32 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 64 rows affected (0.00 sec) Records: 64 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 128 rows affected (0.00 sec) Records: 128 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 256 rows affected (0.00 sec) Records: 256 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 512 rows affected (0.01 sec) Records: 512 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 1024 rows affected (0.01 sec) Records: 1024 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 2048 rows affected (0.01 sec) Records: 2048 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 4096 rows affected (0.03 sec) Records: 4096 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 8192 rows affected (0.05 sec) Records: 8192 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 16384 rows affected (0.11 sec) Records: 16384 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 32768 rows affected (0.19 sec) Records: 32768 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 65536 rows affected (0.37 sec) Records: 65536 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 131072 rows affected (0.72 sec) Records: 131072 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 262144 rows affected (1.51 sec) Records: 262144 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 524288 rows affected (2.86 sec) Records: 524288 Duplicates: 0 Warnings: 0 mysql> insert into a values (2); Query OK, 1 row affected (0.00 sec) mysql> explain select a from a where a = 1 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: ref possible_keys: a key: a key_len: 5 ref: const rows: 523498 Extra: Using index 1 row in set (0.00 sec) mysql> explain select a from a where a = 1 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: ref possible_keys: a key: a key_len: 5 ref: const rows: 523498 Extra: Using index 1 row in set (0.00 sec) mysql> explain select a from a where a = 2 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: ref possible_keys: a key: a key_len: 5 ref: const rows: 1 Extra: Using index 1 row in set (0.00 sec) mysql> alter table a add b int default 1; Query OK, 0 rows affected (4.55 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> explain select a,b from a where a = 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: ref possible_keys: a key: a key_len: 5 ref: const rows: 523441 Extra: NULL 1 row in set (0.00 sec) mysql> select a,b from a ignore index(a) where a = 1 ; +------+------+ 1048576 rows in set (0.64 sec) mysql> select a,b from a where a = 1 ; +------+------+ 1048576 rows in set (1.49 sec) mysql> mysql> explain select a,b from a ignore index(a) where a = 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1046883 Extra: Using where 1 row in set (0.00 sec)
[16 Jan 2015 9:57]
MySQL Verification Team
// 5.7.6 mysql> show variables like '%version%'; +-------------------------+---------------------------------------------------------+ | Variable_name | Value | +-------------------------+---------------------------------------------------------+ | innodb_version | 5.7.6 | | protocol_version | 10 | | slave_type_conversions | | | version | 5.7.6-m16-enterprise-commercial-advanced | | version_comment | MySQL Enterprise Server - Advanced Edition (Commercial) | | version_compile_machine | x86_64 | | version_compile_os | Linux | +-------------------------+---------------------------------------------------------+ 7 rows in set (0.00 sec) mysql> create table a(a int,key(a)) engine=innodb; Query OK, 0 rows affected (0.00 sec) mysql> insert into a values (1); Query OK, 1 row affected (0.00 sec) mysql> insert into a select * from a; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 8 rows affected (0.00 sec) Records: 8 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 16 rows affected (0.00 sec) Records: 16 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 32 rows affected (0.00 sec) Records: 32 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 64 rows affected (0.00 sec) Records: 64 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 128 rows affected (0.00 sec) Records: 128 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 256 rows affected (0.00 sec) Records: 256 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 512 rows affected (0.00 sec) Records: 512 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 1024 rows affected (0.01 sec) Records: 1024 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 2048 rows affected (0.02 sec) Records: 2048 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 4096 rows affected (0.04 sec) Records: 4096 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 8192 rows affected (0.09 sec) Records: 8192 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 16384 rows affected (0.17 sec) Records: 16384 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 32768 rows affected (0.32 sec) Records: 32768 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 65536 rows affected (0.62 sec) Records: 65536 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 131072 rows affected (1.26 sec) Records: 131072 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 262144 rows affected (2.61 sec) Records: 262144 Duplicates: 0 Warnings: 0 mysql> insert into a select * from a; Query OK, 524288 rows affected (5.22 sec) Records: 524288 Duplicates: 0 Warnings: 0 mysql> insert into a values (2); Query OK, 1 row affected (0.00 sec) mysql> explain select a from a where a = 1 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a partitions: NULL type: ref possible_keys: a key: a key_len: 5 ref: const rows: 523673 filtered: 100.00 Extra: Using index 1 row in set, 1 warning (0.00 sec) mysql> explain select a from a where a = 2 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a partitions: NULL type: ref possible_keys: a key: a key_len: 5 ref: const rows: 1 filtered: 100.00 Extra: Using index 1 row in set, 1 warning (0.00 sec) mysql> alter table a add b int default 1; Query OK, 0 rows affected (1.88 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> explain select a,b from a where a = 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a partitions: NULL type: ref possible_keys: a key: a key_len: 5 ref: const rows: 523446 filtered: 100.00 Extra: NULL 1 row in set, 1 warning (0.00 sec) mysql> select a,b from a ignore index(a) where a = 1 ; +------+------+ 1048576 rows in set (0.64 sec) mysql> select a,b from a where a = 1 ; +------+------+ 1048576 rows in set (1.51 sec) mysql> explain select a,b from a ignore index(a) where a = 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a partitions: NULL type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1046892 filtered: 100.00 Extra: Using where 1 row in set, 1 warning (0.00 sec)