删除不必要的索引
为每个查询创建索引可能导致不必要的索引,这会降低数据库性能。不必要的索引可能很少使用,由于另一个复合索引的覆盖而冗余,或者根本不使用。为了优化数据库性能,最小化使用索引的数量非常重要。识别并删除不必要的索引,以保持高效的查询执行和资源使用。
关于此任务
考虑以下内容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 性能顾问(适用于 M10 集群或更高版本)和 MongoDB Compass 来确定、隐藏和删除不必要的索引。
隐藏索引
在确定不必要的索引后,您可以使用 db.collection.hideIndex()
方法隐藏索引,并在删除之前评估其对数据库的影响。
db.courses.hideIndex( "days_1" ) db.courses.hideIndex( "time_1" ) db.courses.hideIndex( "building_1" )
删除索引
如果您确定索引是不必要的并且对性能有负面影响,则可以使用 db.collection.dropIndexes()
方法删除索引。
db.courses.dropIndexes( [ "days_1", "time_1", "building_1" ] )
在这个例子中,只有以下索引仍然存在,因为它们是使用最频繁的,有助于优化查询
_id
默认是索引的{ course_name: 1 }
{ professor: 1 }
{ semester: 1 }
{ day: 1, time: 1 }