🔹 1. 复合索引(Compound Index)
👉 定义:对多个字段建立的索引,例如:
规则:最左前缀原则
-
索引
{a:1, b:1, c:1}
可以支持:-
{a}
-
{a, b}
-
{a, b, c}
-
-
不支持
{b}
或{c}
单独查询。
案例:订单表
常见查询:
-
查询某个用户的订单 →
user_id
-
查询用户最近订单 →
user_id + created_at
-
按状态统计订单 →
status
索引设计:
📌 注意:
如果写成 {created_at: -1, user_id: 1}
,就没法支持 "user_id=xx 且按时间排序" 的查询。
🔹 2. 多键索引(Multikey Index)
👉 定义:当索引字段是 数组 时,MongoDB 会自动创建 多键索引,对数组里的每个元素建索引。
案例:文章评论
索引:
查询:
👉 直接走多键索引。
⚠️ 限制:
-
一个查询最多只能涉及一个多键索引
-
如果有两个数组字段同时出现在查询条件里,索引可能失效。
-
例:
{ tags: "nosql", comments.user: "Alice" }
-
-
多键索引不能保证数组内元素的组合唯一性
-
比如
{tags: ["a","b"]}
和{tags:["b","a"]}
,都会被索引成两个值。
-
优化建议:
-
如果数组数据量特别大,考虑拆成独立 collection,而不是用多键索引。
-
多键索引适合标签、分类这种数据量较小的数组。
🔹 3. 大数据量表的索引
当表数据量上百万甚至上亿时,索引设计更重要:
案例:日志表
常见查询场景:
-
查某个服务的日志(按时间范围)
-
查最新错误日志
-
自动清理 30 天前的数据
索引设计:
大表索引设计规范
-
索引要精简:
-
不要给低选择性字段(如
status=0/1
)单独建索引。 -
如果必须查询这种字段,最好和高选择性字段组合。
-
-
覆盖索引(Covered Index)
-
查询只用到索引里的字段,MongoDB 可以直接返回结果,不用回表。
-
例:
👉 查询结果只用到索引里的字段 → 覆盖查询,速度更快。
-
-
分页优化
-
大数据量下
skip
慢(需要扫描跳过前 N 行)。 -
解决方案:用 范围查询 + limit 代替
skip
。 -
例:
-
🔹 4. 对比总结
类型 | 特点 | 使用场景 | 注意事项 |
---|---|---|---|
复合索引 | 多字段组合索引,最左前缀规则 | 用户+时间、文章+创建时间 | 字段顺序很重要 |
多键索引 | 数组字段自动展开建索引 | 标签、分类、少量子数据 | 数组过大性能差;不能同时用多个多键索引 |
大数据量表索引 | 结合复合索引、TTL、覆盖索引 | 日志、订单、监控数据 | 避免低选择性索引;分页要优化 |
✅ 总结建议
-
复合索引:遵循查询习惯 & 最左前缀原则
-
多键索引:适合小数组字段,数组太大就拆表
-
大数据量表:优先设计复合索引 + 覆盖索引,避免低选择性字段