删除不必要的索引
为每个查询创建索引可能会导致创建不必要的索引,从而降低数据库性能。 不必要的索引可能很少使用、由于被另一个复合索引覆盖而变得多余,或者根本不使用。 为了优化数据库性能,尽量减少使用的索引数量非常重要。 识别并删除不必要的索引,以保持高效的查询执行和资源使用。
关于此任务
考虑以下 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 }
为集合中的每个字段创建索引可能会导致集合臃肿,并对写入性能产生负面影响。
步骤
评估索引使用情况
要确定哪些索引很少使用,请使用 $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来确定、隐藏和删除不必要的索引。
Hide Indexes
确定不必要的索引后,可以使用db.collection.hideIndex()
方法隐藏索引,并在删除索引之前评估其对数据库的影响。
db.courses.hideIndex( "days_1" ) db.courses.hideIndex( "time_1" ) db.courses.hideIndex( "building_1" )
dropIndexes
如果您确定索引是不必要的并且对性能有负面影响,请使用db.collection.dropIndexes()
方法删除索引。
db.courses.dropIndexes( [ "days_1", "time_1", "building_1" ] )
在此示例中,仅保留以下索引,因为它们使用最频繁,有助于优化查询:
_id
默认已编制索引{ course_name: 1 }
{ professor: 1 }
{ semester: 1 }
{ day: 1, time: 1 }