跳转到页面内容
圆点软件.YUANDIAN SOFTWARE

YUANDIAN / INSIGHTS & IDEAS

MySQL 联合索引设计的字段顺序与选择性判断

联合索引的顺序不是拍脑袋定的。结合真实查询条件、选择性和回表代价来判断字段先后,再用执行计划逐条验证。

专注软件开发 · 连接业务与可能技术分享
MySQL 联合索引设计的字段顺序与选择性判断

从查询模式反推索引

索引不是按表设计,而是按查询设计。先把线上真实的过滤、排序、关联条件收集起来,按字段组合归类,再决定建几个索引。

最左前缀原则决定顺序:等值条件放前面,范围条件放后面。顺序写反了,范围条件之后的字段就无法继续用于索引定位。

区分度高的字段放前面通常更好,但不是唯一标准。一个区分度很高却几乎不在查询里单独出现的字段,把它放前面反而浪费了前缀能力。

用执行计划验证而不是猜

建完索引一定用执行计划看一遍。重点看访问类型是否达到范围扫描或等值匹配、是否命中预期索引、估算行数量级、附加信息里有没有出现文件排序和临时表。

访问类型显示为全索引扫描时,说明索引没起到过滤作用,只是利用了有序性。出现文件排序时先看排序字段能否并入索引,让排序直接走索引顺序。

估算由统计信息驱动,不等于实际。表刚经历大批量写入,统计信息可能滞后,必要时手动更新统计再判断,不要因为一次估算偏差就否定索引。

覆盖索引与回表

查询只需要索引里已有的列时,可以直接从索引返回,不必回表取整行。把查询用到的小字段加进索引末尾,能省掉一次随机读。

代价是索引变大、写入变慢。只给高频且字段稳定的查询加覆盖索引,不要为了省回表把整张表的列都塞进索引。

主键本身就在二级索引里,查询用到主键字段时不需要额外包含。这一点在组合索引的字段选择上容易被忽略。

索引数量与写入成本

每个二级索引都要在写入时同步维护。一张写入频繁的表挂上七八个索引,插入和更新的开销会明显上升,还会占用更多缓冲池。

用不到的索引要定期清理。通过性能视图统计索引的使用次数,长期为零的索引在确认没有低频报表查询依赖后可以删除。

两个索引的前缀完全重合时,短的那个通常可以删掉。字段顺序只差末尾一两个的场景,优先保留能覆盖更多查询的那个。

约束设计与变更安全

唯一索引既是查询手段也是约束手段。注册名、订单号这类天然唯一的字段,用唯一索引在数据库层兜底,比只在应用层判断可靠。

注意唯一索引对空值的处理,多个空值通常不冲突,依赖它做去重时要想清楚语义。软删除场景下唯一索引会把已删除记录也算进去,常见做法是把删除标记列纳入索引,或者把删除记录的标记列置为记录主键。

线上大表直接加索引会阻塞写入,需要用在线变更工具做无锁调整,并在业务低峰执行,变更前评估磁盘空间与主从延迟。

删除索引同样要谨慎,先确认没有隐藏依赖,再按灰度节奏处理。保留变更记录,出问题时能快速回退。

MySQL索引设计

LET’S BUILD TOGETHER

让思考,成为下一步行动。

把业务场景与初步想法告诉我们,一起找到合适的实现方式。