索引的查看与删除
索引运维围绕三件事:看清现在有哪些索引、确认某个索引是否还有人用、安全地删掉冗余索引。getIndexes 列出索引定义与选项,dropIndex 按名称或字段组合删除,dropIndexes 一次性清空(_id 索引除外)。删除前用 explain 观察执行计划,或先把索引隐藏起来观察一段时间,比直接删除稳妥得多。
基本信息
| 查看 | db.coll.getIndexes() |
|---|---|
| 删除单个 | db.coll.dropIndex("status_ts") 或按字段组合 db.coll.dropIndex({ status: 1, ts: -1 }) |
| 删除全部 | db.coll.dropIndexes()(_id 索引除外) |
| 临时隐藏 | db.coll.hideIndex(name) 与 unhideIndex(name)(4.4 及以上) |
| 构建行为 | 大集合建索引建议在低峰执行,并注意少数派确认与提交点设置 |
| 权限要求 | 需要集合的 index 相关权限 |
典型使用场景
- 索引瘦身:找出长期未被使用的索引,减少写入放大与磁盘占用
- 验证依赖:先隐藏可疑索引,观察查询延迟与执行计划变化再决定删除
- 重建调整:为同一字段组重建不同方向或不同选项的索引
- 环境核对:比对生产与测试环境的索引差异,避免性能表现不一致
- 上线前检查:确认新功能所需索引已经建好,而不是依赖数据库自动扫描
示例
示例
// 查看现有索引与选项(含唯一、稀疏、部分索引等设置)
db.orders.getIndexes()
// 按名称删除单个索引
db.orders.dropIndex("status_ts")
// 按字段组合删除:方向也要与原索引一致
// db.orders.dropIndex({ status: 1, ts: -1 })
// 先隐藏再观察:隐藏后优化器不再选用,但索引仍随写入维护
db.orders.hideIndex("status_ts")
// db.orders.unhideIndex("status_ts") -- 确认无影响后再删除
// 危险操作:清空除 _id 外的全部索引
db.orders.dropIndexes()操作读法
| 操作 | 行为 | 风险与注意 |
|---|---|---|
| getIndexes | 列出索引名、键与选项 | 关注 name 与 key 是否与预期一致 |
| dropIndex(name) | 删除指定索引 | 名称拼错会报错,不会误删其他索引 |
| dropIndex(键组合) | 按字段组合删除 | 方向必须完全匹配现有索引 |
| dropIndexes | 清空除 _id 外全部索引 | 大集合重建代价高,执行前必须确认 |
| hideIndex | 隐藏索引,不再被查询使用 | 仍占空间并随写入维护,属验证手段 |
| unique | 唯一约束 | 重复数据存在时创建会失败,需先清理 |
删除索引前先隐藏:隐藏后索引仍会被维护,只是优化器不再选择它,观察一到两个业务周期内的查询延迟,确认无影响再删除,回退成本几乎为零。
dropIndexes 会移除除 _id 外全部索引:大集合上重建需要长时间扫描,且期间查询会退化为全表扫描,执行前务必确认。