在5.1.46中优化器在对primary key的选择上做了一点改动:
Performance: While looking for the shortest index for a covering index scan, the optimizer did not consider the full row length for a clustered primary key, as in InnoDB. Secondary covering indexes will now be preferred, making full table scans less likely。
该版本中增加了find_shortest_key函数,该函数的作用可以认为是选择最小key length的
索引来满足我们的查询。
该函数是怎么工作的:
复制代码 代码如下:What find_shortest_key should do is the following. If the primary key is a covering index
and is clustered, like in MyISAM, then the behavior today should remain the same. If the
primary key is clustered, like in InnoDB, then it should not consider using the primary
key because then the storage engine will have to scan through much more data.
调用Primary_key_is_clustered(),当返回值为true,执行find_shortest_key:选择key length最小的覆盖索引(Secondary covering indexes),然后来满足查询。
首先在5.1.45中测试:
$mysql -V
mysql Ver 14.14 Distrib 5.1.45, for unknown-linux-gnu (x86_64) using EditLine wrapper
root@test 03:49:45>create table test(id int,name varchar(20),name2 varchar(20),d datetime,primary key(id)) engine=innodb;
Query OK, 0 rows affected (0.16 sec)
root@test 03:49:47>insert into test values(1,'xc','sds',now()),(2,'xcx','dd',now()),(3,'sdds','ddd',now()),(4,'sdsdf','dsd',now()),(5,'sdsdaa','sds',now());
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
root@test 03:49:51>
root@test 03:49:51>insert into test values(6,'xce','sdsd',now()),(7,'xcx','sdsd',now()),(8,'sdds','sds',now()),(9,'sdsdsdf','sdsdsd',now()),(10,'sdssdfdaa','sdsdsd',now());
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
创建索引ind_1:
root@test 03:49:53>alter table test add index ind_1(name,d);
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
root@test 03:50:08>explain select count(*) from test;
+—-+————-+——-+——-+—————+———+———+——+——+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——-+—————+———+———+——+——+————-+
| 1 | SIMPLE | test | index | NULL | PRIMARY | 4 | NULL | 10 | Using index |
+—-+————-+——-+——-+—————+———+———+——+——+————-+
1 row in set (0.00 sec)
添加ind_2: