CREATE TABLE `yonghu` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '??',
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '????',
`zhanghao` varchar(200) NOT NULL COMMENT '??',
`mima` varchar(200) NOT NULL COMMENT '??',
`xingming` varchar(200) NOT NULL COMMENT '??',
`xingbie` varchar(200) DEFAULT NULL COMMENT '??',
`lianxidianhua` varchar(200) DEFAULT NULL COMMENT '????',
`member` int DEFAULT '0',
`discounts` int DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `zhanghao` (`zhanghao`),
KEY `idx_zhanghao_member` (`zhanghao`,`member`)
) ENGINE=InnoDB AUTO_INCREMENT=1707209867641 DEFAULT CHARSET=utf8mb3 COMMENT='??'
我有一张甬湖桌。 zhanghao字段是唯一索引,我使用zhanghao和成员字段创建了复合索引。下面的SQL,我感觉应该使用复合索引更快。为什么Mysql选择使用唯一索引?
mysql> EXPLAIN select member from yonghu where zhanghao ="asd";
+----+-------------+--------+------------+-------+------------------------------+----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+------------------------------+----------+---------+-------+------+----------+-------+
| 1 | SIMPLE | yonghu | NULL | const | zhanghao,idx_zhanghao_member | zhanghao | 602 | const | 1 | 100.00 | NULL |
+----+-------------+--------+------------+-------+------------------------------+----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
删除zhanghao唯一索引后我将使用复合索引,并且解释的类型为·ref·,唯一索引的类型为·const·从类型上看,它仍然是唯一索引。复合索引不是不需要返回表吗?不是应该更快吗?
mysql> EXPLAIN select addtime from yonghu where zhanghao ="asd";
+----+-------------+--------+------------+------+---------------------+---------------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------------+---------------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | yonghu | NULL | ref | idx_zhanghao_member | idx_zhanghao_member | 602 | const | 1 | 100.00 | NULL |
+----+-------------+--------+------------+------+---------------------+---------------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
一般来说,如果索引覆盖了该字段,就像你说的那样,就不需要回表来查询其他字段了。
但是,如果有唯一索引,并且sql是
=
查询,那么使用唯一索引是更好的选择。因为如果在唯一索引中找到了要查询的值,则不需要继续扫描并索引剩余索引,但如果使用其他索引,则需要继续扫描,直到出现其他值。
另外,唯一索引和=
查询意味着满足的数据不会超过一行,所以如果需要返回表,它仍然很快,并且不会有明显的性能差异。
如果你的sql是像
select member from yonghu where zhanghao >"asd";
这样的范围查询,它会使用idx_zhanghao_member
,如果使用唯一索引,它会返回表,所以它比覆盖索引效率低。
BTW,如果你想验证索引执行的效率,你需要准备更多的数据,因为
Indexes are less important for queries on small tables, or big tables where report queries process most or all of the rows.