Docs 菜单
Docs 主页
/
MongoDB Manual
/ /

删除不必要的索引

在此页面上

  • 关于此任务
  • 步骤
  • 评估索引使用情况
  • Hide Indexes
  • dropIndexes
  • 了解详情

为每个查询创建索引可能会导致创建不必要的索引,从而降低数据库性能。不必要的索引可能很少使用、由于被另一个复合索引覆盖而变得多余,或者根本不使用。为了优化数据库性能,尽量减少使用的索引数量非常重要。识别并删除不必要的索引,以保持高效的查询执行和资源使用。

考虑以下 courses集合,其中每个文档都存储有关不同学校课程的信息。

// Biology course document
db.courses.insertOne(
{
_id: 1,
course_name: "Biology 101",
professor: "Tate",
semester: "Fall",
days: "Monday, Friday",
time: "12:00",
building: "Olson"
}
)

courses 集合具有针对每个字段的索引:

  • _id 默认已编制索引

  • { course_name: 1 }

  • { professor: 1 }

  • { semester: 1 }

  • { building: 1 }

  • { days: 1 }

  • { time: 1 }

  • { day: 1, time: 1 }

为集合中的每个字段创建索引可能会导致集合臃肿,并对写入性能产生负面影响。

1

要确定哪些索引很少使用,请使用 $indexStats聚合阶段:

db.courses.aggregate( [ { $indexStats: { } } ] )

该操作返回以下内容:

[
{
name: "building_1",
key: { "building": 1 },
host: "M-C02FJ3BDML85:27017",
accesses: { "ops": "Long('0')", "since": "ISODate('2024-06-24T17:35:00.000Z')" },
spec: { "v": 2, "key": { "building": 1 }, "name": "building_1" }
},
{
name: "day_1",
key: { "day": 1 },
host: "M-C02FJ3BDML85:27017",
accesses: { "ops": "Long('1')", "since": "ISODate('2024-06-24T17:35:30.000Z')" },
spec: { "v": 2, "key": { "day": 1 }, "name": "day_1" }
},
{
name: "time_1",
key: { "time": 1 },
host: "M-C02FJ3BDML85:27017",
accesses: { "ops": "Long('1')", "since": "ISODate('2024-06-24T17:36:00.000Z')" },
spec: { "v": 2, "key": { "time": 1 }, "name": "time_1" }
},
{
name: "day_1_time_1",
key: { "day": 1, "time": 1 },
host: "M-C02FJ3BDML85:27017",
accesses: { "ops": "Long('110')", "since": "ISODate('2024-06-24T17:31:21.800Z')" },
spec: { "v": 2, "key": { "day": 1, "time": 1 }, "name": "day_1_time_1" }
},
{
name: "_id_",
key: { "_id": 1 },
host: "M-C02FJ3BDML85:27017",
accesses: { "ops": "Long('150')", "since": "ISODate('2024-06-24T15:31:49.463Z')" },
spec: { "v": 2, "key": { "_id": 1 }, "name": "_id_" }
},
{
name: "course_name_1",
key: { "course_name": 1 },
host: "M-C02FJ3BDML85:27017",
accesses: { "ops": "Long('120')", "since": "ISODate('2024-06-24T17:29:26.344Z')" },
spec: { "v": 2, "key": { "course_name": 1 }, "name": "course_name_1" }
},
...
]
  • 可以删除building_1索引,因为它未用于任何查询,如其accesses计数为零所示。

  • 可以删除{ days: 1 }{ time: 1 }索引,因为复合索引{ day: 1, time: 1 }涵盖与时间相关的查询。

您还可以使用 MongoDB Atlas Performance Advisor (适用于 M 10或更大的集群)和MongoDB Compass来确定、隐藏和删除不必要的索引。

2

确定不必要的索引后,可以使用db.collection.hideIndex()方法隐藏索引,并在删除索引之前评估其对数据库的影响。

db.courses.hideIndex( "days_1" )
db.courses.hideIndex( "time_1" )
db.courses.hideIndex( "building_1" )
3

如果您确定索引是不必要的并且对性能有负面影响,请使用db.collection.dropIndexes()方法删除索引。

db.courses.dropIndexes( [ "days_1", "time_1", "building_1" ] )

在此示例中,仅保留以下索引,因为它们使用最频繁,有助于优化查询:

  • _id 默认已编制索引

  • { course_name: 1 }

  • { professor: 1 }

  • { semester: 1 }

  • { day: 1, time: 1 }

后退

减少集合数量