468 字
2 分钟
MySQL 普通索引和唯一索引如何选择
唯一索引的首要价值是保证列值唯一;普通索引只用于查找,不提供唯一性约束。若业务规则要求邮箱、订单号不可重复,应使用唯一约束,而不是寄希望于应用先查再写,因为并发请求可能同时通过检查。MySQL 唯一索引对 NULL 的处理允许存在多个 NULL(具体受列定义和组合列语义影响),若要求必填还需 NOT NULL。
“唯一索引比普通索引查询慢很多”不是普遍结论。两者都能通过 B+ 树定位;唯一性会影响查找可提前终止的判断,写入时需要检查冲突。在 MySQL 8.0 的 InnoDB 中,change buffer 可缓冲部分尚未驻留 Buffer Pool 的非唯一二级索引变更;唯一索引插入需要检查重复键,不能以同样方式缓冲。实际读写差异仍由缓存命中、数据分布和负载决定。
选择的核心是数据语义,其次才是基准测试。不要为了理论上的微小读取差异放弃正确约束,也不要给并不唯一的业务字段错误添加唯一索引。在线创建唯一约束前应先清理重复数据,并处理并发写入和 DDL 影响。
追问
- 唯一索引能否代替应用查重? 它应是并发正确性的最终保障;应用仍可提前校验以改善提示,但必须处理唯一键冲突。
- 唯一列上查询一定比普通索引快吗? 不一定有可测差异,二者通常都能快速定位,应按真实负载测试。
- 唯一索引列可以有多个 NULL 吗? MySQL 通常允许多个 NULL,因为 NULL 不被视为相等;要限制空值需另加
NOT NULL。
MySQL 普通索引和唯一索引如何选择
https://blog.xqcherry.top/posts/interview/mysql/unique-index-vs-normal-index/ 目录