滚动新闻 →
朝鲜黑客攻击币安 逾63亿美元损失曝光 油价飙升冲击货运行业 多地出现倒闭潮 A股10月暴跌惨重 散户损失惨重频传跳楼 AI工具误引错误网站数据误导选民 美国女死囚注射两剂死刑药物未亡 首次公开讲述经历 中国三大航票务系统受韩国仁川机场网络故障影响瘫痪 以色列大选揭晓 内塔尼亚胡未达半数席位 美国议员要求升级赴华旅行警示 中国被指实施人质外交 MySQL 普通索引、唯一索引和主键索引应该怎样选择 美军中央司令部向川普汇报伊朗军事选项 十架运输机部署以色列 辽宁康平中学肺结核筛查涉78名学生共用针头 专家警示感染风险 美国限制中国科技产品入境 王国臣:禁令影响或超关税 多行业欠薪潮蔓延 大陆经济持续低迷 普京表态支持恢复与欧洲关系 俄乌冲突持续升级 泰国劳资冲突致中国老板遇害,四名嫌疑人落网 黄乐履历存疑 被指与中共情报往来 反诈博主徽剑遇害案引争议 主犯律师费疑点重重 欧洲三国抗议浪潮再起 德国忧法国动荡重现 币安疑似遭遇黑客攻击 比特币跌破7.8万美元 白宫万圣节派糖活动:川普夫妇与空军一号共庆 赖清德警告中共介入台北市长选举 指控黑道与第五纵队干预 猫也“辱华”了 Hello Kitty母公司道歉 诺维萨德事故引爆塞尔维亚政坛震荡 币安遭黑客攻击 60亿美元失窃引资金安全疑虑 辽宁某高中肺结核筛查遭质疑:200名学生共用针头引家长抗议 美国拟禁中国电信商直连美国电话号码以打击诈骗 委内瑞拉2027年总统大选临近 马查多获美支持参选 五中全会闭幕后 中纪委披露十八大以来反腐成果 专业大厨揭秘:冷水煮马铃薯更易入味 广东两校学生因停电闷热抗议 10月30日维权动态 中国古典文学中的友情为什么如此动人 西南地区的传统药食文化 黄逸豪揭露遭买凶追杀细节:幸免于难 霍尔木兹海峡三油轮遇袭 川普调整竞选行程 乌军千架无人机突袭俄本土 局部停火持续第四日 马斯克警告民主党全面执政或颠覆美国政治格局 意大利、德国、法国抗议四起 这个周末不平静 华为进军制药业引争议 网民担忧速成药风险 朝鲜黑客组织疑似盗取币安63亿美元资产 中国古代书房究竟是什么样的

MySQL 普通索引、唯一索引和主键索引应该怎样选择

发布时间: 2026-10-30 12:00:02    最后更新: 2026-10-30 12:43:54    阅读:6  约7 分钟阅读     

MySQL 普通索引、唯一索引和主键索引应该怎样选择
图片说明:示意图   图片来源:Public Domain(公有领域)
在MySQL开发中,普通索引、唯一索引和主键索引经常被放在一起讨论,但它们解决的其实不是同一个问题。主键首先解决的是“这条记录是谁”,唯一索引解决的是“这个值能不能重复”,普通索引解决的是“怎样更快找到符合条件的数据”。如果把三者简单理解成不同速度等级的索引,很容易在数据库设计阶段做出错误选择。

对于使用InnoDB的MySQL表,主键还有一个特殊作用:主键索引就是聚簇索引,数据行本身按照主键组织在B+Tree的叶子节点中。因此,主键不仅是一个约束,同时也是InnoDB组织数据的重要基础。

主键应该优先考虑稳定、短小、唯一的标识符。自增整数是传统选择,因为插入记录时通常按照递增方向追加,可以减少随机插入带来的B+Tree页分裂和空间管理压力。不过这并不意味着所有系统都必须使用AUTO_INCREMENT。UUID、业务生成的有序ID以及其他分布式ID方案同样可以作为主键,但需要考虑索引长度、插入顺序以及生成策略。

主键还有一个容易被忽略的影响:InnoDB的普通二级索引叶子节点中会保存主键值,用于回表定位数据。因此主键过长,会放大其他二级索引的存储空间和维护成本。一个包含大量二级索引的大型SaaS系统,如果采用很长的字符串作为主键,影响可能远远超过主键自身占用的空间。

唯一索引解决的是另外一个问题。假设用户表规定邮箱地址不能重复,那么数据库应该通过UNIQUE约束或者唯一索引真正保证这个规则,而不是先执行一次SELECT检查,然后再INSERT。单纯依靠应用层检查存在竞态条件:两个并发请求可能同时检查到“邮箱不存在”,随后同时尝试写入。

唯一索引因此既是索引,也是数据完整性约束。手机号、外部系统订单号、租户内部的业务编号等,只要业务规则明确要求不能重复,就应该考虑唯一索引。

需要特别注意NULL。MySQL允许唯一索引中出现NULL,而且NULL与NULL并不按照普通相等值处理,因此一个唯一索引允许存在多个NULL,而不是只能存在一个NULL。不同数据库系统在NULL唯一性上的行为也可能不同,因此设计跨数据库应用时不能简单套用其他数据库的经验。

唯一性还受到字符集和排序规则影响。例如某些不区分大小写的字符排序规则下,'Test@example.com'和'test@example.com'可能被视为相同值。如果业务要求大小写敏感,就必须根据具体字段定义合适的字符集、COLLATE以及数据规范,而不能笼统地说“MySQL默认不区分大小写”。

普通索引则没有唯一性要求。它主要用于改善查询访问路径,例如订单表经常执行WHERE tenant_id=? AND status=? AND created_at>=?这样的查询,就可以根据实际查询模式设计联合索引。联合索引的字段顺序不能只靠“哪个字段选择性高”决定,而应该结合等值条件、范围条件、排序以及分页方式一起判断。

例如常见查询如果总是按照租户和时间查询,那么(tenant_id, created_at)可能比单独建立tenant_id和created_at两个索引更符合实际访问路径。如果查询还经常固定过滤status,则可能进一步形成(tenant_id, status, created_at)。但最终应该通过EXPLAIN、EXPLAIN ANALYZE、慢查询日志以及实际负载验证,而不是套用固定模板。

覆盖索引也是普通索引优化中经常使用的技术。如果查询所需要的字段已经全部包含在索引中,MySQL在特定执行计划下可以直接从索引获得所需数据,减少回表访问。不过覆盖索引不是“索引字段越多越好”。索引一旦变得过宽,就会增加磁盘空间、Buffer Pool占用以及INSERT、UPDATE、DELETE时的维护成本。

这里也需要纠正一个常见误解:不能简单地说“主键查询一定最快,唯一索引其次,普通索引最慢”。真正的性能取决于访问路径、返回行数、索引结构、缓存命中情况、回表成本以及查询本身。

例如通过主键查找单行记录通常非常高效,因为可以直接定位聚簇索引中的记录。但唯一索引查找同样可以快速定位记录,而普通索引如果具有较好的选择性,同样可以非常高效。反过来,如果普通索引对应的条件会返回表中大量记录,即使使用了索引,也可能需要大量回表,甚至优化器最终选择全表扫描。

写入成本也不能简单排序成“普通索引最差、主键最好”。每增加一个相关索引,INSERT、DELETE以及部分UPDATE操作都可能需要维护相应的索引结构。唯一索引还需要进行唯一性检查;主键则决定聚簇索引中的数据组织方式。因此真正应该关注的是索引数量、索引宽度、写入频率、数据分布和页面访问,而不是给三种索引固定排一个性能顺序。

还有一个实际问题经常被忽略:频繁更新的字段并不是因为“更新”两个字就不能建立索引。真正需要考虑的是更新是否频繁改变索引键值。如果一个字段经常变化,而且它参与多个索引,那么每次修改都可能带来更多索引维护工作。对于主键尤其如此,因为InnoDB的主键与聚簇数据组织直接相关,因此通常应该选择稳定的标识符,而不是把经常变化的业务属性作为主键。

实际数据库设计可以按照一个很简单的顺序判断:首先确定表需要什么稳定的主键;然后找出业务上必须唯一的数据,并使用UNIQUE约束保证完整性;最后根据真实查询建立普通索引和联合索引。索引数量则应该根据SQL访问模式和写入压力持续调整,而不是规定“每张表只能有几个索引”。

对于SaaS系统,还必须把tenant_id纳入整体设计。租户ID是否应该出现在联合索引的第一列,取决于实际SQL。如果绝大多数查询都是“某个租户的数据 + 时间范围”,那么(tenant_id, created_at)通常具有自然的访问路径;如果查询模式不同,索引顺序也应该随之调整。更大的租户与普通租户之间如果存在严重的数据量差异,还需要通过执行计划和实际负载观察是否出现数据倾斜。

因此,主键、唯一索引和普通索引并不是三个可以简单比较“谁最快”的选项。主键负责稳定标识和InnoDB聚簇数据组织,唯一索引负责落实业务唯一性,普通索引负责优化查询访问路径。真正成熟的数据库设计,不是给每个字段机械地加一个索引,而是让约束负责保证数据正确,让索引服务于真实SQL,再通过执行计划、慢查询和生产负载不断验证。数据库规模增长以后,索引之外还可能需要考虑分区、归档、读写分离、缓存甚至分库分表,但这些都应该建立在真实瓶颈已经被测量出来的基础上。

喜欢这篇报道?

使用下面的功能,方便以后继续阅读和分享 MNewsTV

设为 Google 新闻首选来源 让 Google 新闻优先显示 MNewsTV 的最新报道 ›
★ 我的收藏 查看已经收藏的文章
关于文章收藏 收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。 删除收藏请进入「我的收藏」进行管理。
分享这篇报道

捐助(Paypal): https://www.paypal.me/observeccp
订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP