技术干货 | MongoDB 功能详解之隐藏索引(Hidden Indexes)
隐藏索引(Hidden Indexes):版本 4.4 中的新功能。
隐藏索引(Hidden indexes)对于查询分析器(query planner)来说是不可见的,不能用于对查询的支持。
通过对查询分析器隐藏索引,用户可以在并未真正删除索引的情况下,评估删除索引所带来的潜在影响。如果影响是负面的,用户可以取消隐藏索引,而不必重新创建已经删除的索引。
行为
除了对查询分析器隐藏之外,隐藏索引的行为与非隐藏索引类似,例如:
- 如果隐藏索引是唯一索引(unique index),索引仍将其唯一约束性应用于文档;
- 如果隐藏索引是过期索引(TTL index),索引仍将使文档过期;
- 隐藏索引仍然包含在 listIndexes和 db.collection.getIndexes() 的结果中;
- 隐藏索引在对集合执行写入操作时更新,并仍然消耗磁盘空间和内存。因此,仍然包含在各种统计操作中,例如 db.collection.stats() 和 $indexStats ;
- 隐藏一个未被隐藏的索引和取消隐藏一个已经隐藏的索引会重置其 $indexStats 。隐藏一个已经被隐藏的索引和取消一个未被隐藏的索引不会重置 $indexStats 。
约束
- 要使用隐藏索引,必须将功能兼容版本(featureCompatibilityVersion)设置为 4.4 或以上版本。但一旦隐藏了索引,在 MongoDB 4.4 二进制包的情况下,即使将功能兼容版本(featureCompatibilityVersion)设置为 4.2,该索引仍然是隐藏的。
- 不能隐藏 _id 索引。
- 不能对隐藏索引使用 cursor.hint() 。
示例
创建隐藏索引
使用 db.collection.createIndex() 并将 hidden 选项设为 true 。
⚠️ 注意:
使用 db.collection.createIndex()
的 hidden 选项,必须将功能兼容版本(featureCompatibilityVersion)设置为 4.4 或以上版本。但一旦隐藏了索引,在 MongoDB 4.4 二进制包的情况下,即使将功能兼容版本(featureCompatibilityVersion)设置为 4.2,该索引仍然是隐藏的。
例如,下面的操作就是在 borough 字段创建一个正序的隐藏索引:
db.addresses.createIndex(
{ borough: 1 },
{ hidden: true }
);
要进行验证,可以在 addresses 集合中执行 db.collection.getIndexes() 操作:
db.addresses.getIndexes()
返回以下结果:
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"borough" : 1
},
"name" : "borough_1",
"hidden" : true
}
]
hidden 选项只有在值为 true 的时候才会返回。
隐藏现有索引
⚠️ 注意:
- 要使用隐藏索引,必须将功能兼容版本(featureCompatibilityVersion)设置为 4.4 或以上版本。但一旦隐藏了索引,在 MongoDB 4.4 二进制包的情况下,即使将功能兼容版本(featureCompatibilityVersion)设置为 4.2,该索引仍然是隐藏的。
- 不能隐藏 _id 索引。
要隐藏已存在的索引,可以使用 collMod 命令或 mongosh 执行 db.collection.hideIndex() 。
例如,创建一个未隐藏的索引:
db.restaurants.createIndex( { borough: 1, ratings: 1 } );
若要隐藏索引,可以使用以下任意方法:
- 使用索引的键执行 db.collection.hideIndex() 方法:
db.restaurants.hideIndex( { borough: 1, ratings: 1 } ); // 指定索引的键
- 使用索引的名字,执行 db.collection.hideIndex() 方法:
db.restaurants.hideIndex( "borough_1_ratings_1" ); // 指定索引名称
要进行验证,可以在 restaurants 集合执行 db.collection.getIndexes() 操作:
db.restaurants.getIndexes()
返回以下结果:
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"borough" : 1,
"ratings" : 1
},
"name" : "borough_1_ratings_1",
"hidden" : true
}
]
hidden 选项只有在值为 true 的时候才会返回。
取消隐藏索引
要取消隐藏索引,可以使用 collMod 命令或 mongosh 执行 db.collection.unhideIndex() 。可以使用以下任意方法:
- 使用索引的键,执行 db.collection.unhideIndex() :
db.restaurants.unhideIndex( { borough: 1, city: 1 } ); // 指定索引的键
- 使用索引的名字,执行 db.collection.unhideIndex() :
db.restaurants.unhideIndex( "borough_1_ratings_1" ); // 指定索引名称
验证,在 restaurants 集合执行 db.collection.getIndexes() :
db.restaurants.getIndexes()
返回以下结果:
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"borough" : 1,
"ratings" : 1
},
"name" : "borough_1_ratings_1"
}
]
索引的 hidden 选项不再显示在 borough_1_ratings_1
索引上,因为 hidden 选项只在值为 true 的时候才会返回。
由于索引在隐藏时是一直维护的,因此在取消隐藏后将立即可用。
原文:Hidden Indexes
关于译者:
司冬雨,MongoDB 中文社区成员,现就职于中国联通软件研究院,目前专注于 MongoDB 数据库运维与技术支持。
文章转载自公众号: Mongoing中文社区