You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询为何选用唯一索引而非联合索引?技术疑问

MySQL索引选择疑问:唯一索引vs联合索引

表结构信息

建表语句如下:

CREATE TABLE `yonghu` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `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+member的联合索引idx_zhanghao_member。

第一次查询及执行计划

执行SQL:

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)

疑问点

我原以为联合索引会更快,但MySQL却选择了唯一索引,这是为什么?删除zhanghao唯一索引后,查询会使用联合索引,此时EXPLAIN的type为ref,而使用唯一索引时type为const。从type来看唯一索引效率更高,但联合索引不需要回表,难道不该更快吗?

删除唯一索引后的查询及执行计划

删除zhanghao唯一索引后,执行SQL:

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)

问题解答

  • 唯一索引的const类型具备绝对确定性:因为zhanghao是唯一索引,MySQL能确定通过该索引可以直接定位到唯一一行数据,const是MySQL中效率最高的查询类型之一,优化器会优先选择这种能精准命中单行的索引路径。
  • 单行场景下覆盖索引的优势被抵消:虽然联合索引idx_zhanghao_member是覆盖索引(包含查询字段member)不需要回表,但唯一索引即使需要回表,也仅需读取单行数据,回表的IO开销几乎可以忽略。优化器计算后认为,const类型的访问成本比ref类型更低,覆盖索引的优势不足以逆转这个判断。
  • 优化器的成本计算逻辑:MySQL优化器会基于表的统计信息(如数据行数、索引基数等)计算不同索引的查询成本,包括IO和CPU开销。在单行查询场景下,const类型的直接定位带来的成本下降,远大于覆盖索引节省的回表开销。
  • 覆盖索引优势的凸显场景:当查询包含多个字段且都在联合索引中,或者表数据量极大导致回表IO开销显著增加时,覆盖索引的优势才会被优化器优先考虑,此时联合索引可能成为首选。

内容的提问来源于stack exchange,提问作者xuekuo hu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:48:16