452 字
2 分钟
联合索引应该如何设计
联合索引应从代表性查询出发,而不是把所有高频字段拼在一起。假设常见查询是 WHERE tenant_id=? AND status=? AND created_at>=? ORDER BY created_at DESC LIMIT 50,候选索引可为 (tenant_id,status,created_at):前两列等值约束形成前缀,时间范围和排序字段位于其后。设计还要检查选择性、字段长度、写入模式和其他查询是否能复用此前缀。
索引顺序不存在固定的“区分度最高永远放第一”口诀。应优先让高频查询的等值条件形成连续前缀,再考虑范围条件、排序和覆盖需求。范围列之后的列通常不能继续缩小同一连续扫描区间,但 ICP 可能利用索引内后列过滤候选记录。若把大字段加入索引以覆盖查询,会增加索引体积和写放大,应比较回表节省与存储成本。
CREATE INDEX idx_order_lookupON orders (tenant_id, status, created_at);用真实参数执行 EXPLAIN,观察 key、rows、排序和回表;同时检查数据分布、索引冗余与更新代价。不要仅凭 SQL 中 WHERE 的书写顺序决定索引,也不要认为优化器必然使用新建索引。
追问
- 等值条件谁放前面? 按查询复用、选择性、排序需求和列宽共同判断;同一组等值列有时可互换,但不能脱离实际查询设计。
- 范围列后面的列完全没用吗? 通常不能继续缩小索引范围,但可能用于 ICP、覆盖或排序等其他环节,须验证执行计划。
- 是否应该把 SELECT 所有列都加入索引? 通常不应;覆盖收益要与索引膨胀、写放大和缓存命中下降权衡。
目录