mysql索引最左匹配原则

转自知乎问题:mysql索引最左匹配原则的理解?

具体问题描述如下:

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `cid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name_cid_INX` (`name`,`cid`),
  KEY `name_INX` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
随便建了一个student表做测试。
create INDEX name_cid_INX ON student(name,cid)
;
create INDEX name_INX ON student(name);
建了两个索引,故意这样建的。
执行1:
EXPLAIN SELECT * FROM student WHERE    name='小红';
依据mysql索引最左匹配原则,两个索引都匹配上了,这个没有问题。。
执行2:
EXPLAIN SELECT * FROM student WHERE   cid=1;
EXPLAIN SELECT * FROM student WHERE   cid=1 AND name='小红';
为什么还能匹配索引。


归纳如下:

(1)沈杰的回复很清楚,第一个查询

select * from student where name = 'xx' and cid = xx;

显然这个查询使用了索引覆盖,因为表存在索引:

KEY `name_cid_INX` (`name`,`cid`)

(2)第二个查询,explain也显示使用了覆盖索引

select * from student where cid = xxx;

因为id是主键,是聚集索引,name,cid是联合索引,那么联合索引里也包含了id,即表中所以的列,不用再回表查询,索引是using index;

(3)根据(2)进行测试,给student新增一列sex,如下

+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | YES  | MUL | NULL    |                |
| cid   | int(11)      | YES  |     | NULL    |                |
| sex   | varchar(8)   | YES  |     |         |                |
+-------+--------------+------+-----+---------+----------------+

再次执行(2),得到的explain信息如下:

+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | student | ALL  | NULL          | NULL | NULL    | NULL |    7 | Using where |
证明(2)是正确的,这里如果有兴趣可以使用optimizer_trace看看执行计划。

猜你喜欢

转载自blog.csdn.net/cjqh_hao/article/details/80723049