MySQL 联合索引 最左匹配原则 20

07-25 11:55 345 1

建表语句:

CREATE TABLE `t_1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `f_1` varchar(255) DEFAULT NULL,
  `f_2` varchar(255) DEFAULT NULL,
  `f_3` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_fh` (`f_1`,`f_2`,`f_3`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

索引 index_fh 是f_1、f-2、f_3三个字段创建的联合索引。

根据最左匹配原则,

select * from abcd where f_1 = '1';
select * from abcd where f_1 = '1' and f_2 = '1';
select * from abcd where f_1 = '1' and f_2 = '1' and f_3 = '1';

上面三个sql语句会使用索引 index_fh
但是

select * from abcd where f_2 = '1';
select * from abcd where f_3 = '1';
select * from abcd where f_2 = '1' and f_3 = '1';

应该不会使用索引,可是使用 explain 查看查询计划,仍然使用了索引。

+------+-------------+-------+-------+---------------+----------+---------+------+------+--------------------------+
| id   | select_type | table | type  | possible_keys | key      | key_len | ref  | rows | Extra                    |
+------+-------------+-------+-------+---------------+----------+---------+------+------+--------------------------+
|    1 | SIMPLE      | t_1  | index | NULL          | index_fh | 2304    | NULL |    1 | Using where; Using index |
+------+-------------+-------+-------+---------------+----------+---------+------+------+--------------------------+

建表语句:

CREATE TABLE `t_2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `f_1` varchar(255) DEFAULT NULL,
  `f_2` varchar(255) DEFAULT NULL,
  `f_3` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_fh` (`f_2`,`f_3`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

建表语句和上面基本相同,只是索引使用了f_2、f_3两个字段,此时查询语句

建表语句和上面基本相同,只是索引使用了f_2、f_3两个字段,此时查询语句

查看查询计划

+------+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+------+-------------+-------+------+---------------+------+---------+------+------+-------------+
|    1 | SIMPLE      | t_2   | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
+------+-------------+-------+------+---------------+------+---------+------+------+-------------+

没有使用索引。

为什么 select * from t_2 where f_3 = '1'; 在两个表中都不符合最左匹配原则,查询时一个使用了索引,一个没使用索引?

做一条咸鱼不可怕,做一条瞎蹦跶的咸鱼最可怕。
0 人点赞
1 条回答
排序方式 时间 投票
草芥 9
举报 1楼

覆盖索引,如果加个字段f_4就不会走索引了。

Up骚年
举报 2楼
多谢大神。
请登录后发表评论
站长 @ 十七度
文章
307
粉丝
18
喜欢
140
收藏
22
排名 : 1
访问 : 56.62万
私信
相似问题