MongoDB中的隐藏索引
官方文档:.0/core/index-hidden/
从MongoDB5.0开始引入了隐藏索引这个特性
隐藏索引对查询规划器不可见,且不能用于支持查询。
使用场景:
通过向规划器隐藏索引,您可以评估在不实际删除索引的情况下删除索引的潜在影响。如有不利影响,您可以取消隐藏该索引,而不必重新创建删除的索引。
行为
- 除了对规划器隐藏之外,隐藏索引的行为与未隐藏索引相同。例如:
- 如果隐藏索引是唯一索引,则该索引仍将其唯一约束应用于文档。
- 如果隐藏索引是 TTL 索引,该索引仍会使文档过期。
- 隐藏的索引包含在 listIndexes 和 db.collection.getIndexes() 结果中。
- 隐藏索引在对集合执行写入操作时进行更新,并继续消耗磁盘空间和内存。因此,它们包含在各种统计操作中,例如 db.collection.stats() 和 $indexStats。
- 隐藏未隐藏索引或取消隐藏索引都会重置其 $indexStats。隐藏已隐藏的索引或取消隐藏已取消隐藏的索引不会重置 $indexStats。
限制
- 要隐藏索引,必须将 featureCompatibilityVersion 设置为 5.0 或更大。
- 您无法隐藏 _id 索引。
- 不能 cursor.hint() 隐藏的索引。
实验
代码语言:txt复制插入测试数据
rs01 [direct: primary] test> db.addresses.insertOne({"borough":"abcd"})
rs01 [direct: primary] test> db.addresses.insertOne({"borough":"defg"})
rs01 [direct: primary] test> db.addresses.find()
[
{ _id: ObjectId('680c6e3818c8de83cf964033'), borough: 'abcd' },
{ _id: ObjectId('680c6e3e18c8de83cf964034'), borough: 'defg' }
]
创建一个隐藏索引
rs01 [direct: primary] test> db.addresses.createIndex(
{ borough: 1 },
{ hidden: true }
);
查看索引清单
rs01 [direct: primary] test> db.addresses.getIndexes()
[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{ v: 2, key: { borough: 1 }, name: 'borough_1', hidden: true }
]
查询测试
rs01 [direct: primary] test> db.addresses.find({"borough":"abcd"}).explain()['queryPlanner']['winningPlan']
{
stage: 'COLLSCAN',
filter: { borough: { '$eq': 'abcd' } },
direction: 'forward'
}
取消索引的hidden属性
rs01 [direct: primary] test> db.addresses.unhideIndex( "borough_1" );
{
hidden_old: true,
hidden_new: false,
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1745644936, i: 1 }),
signature: {
hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
keyId: Long('0')
}
},
operationTime: Timestamp({ t: 1745644936, i: 1 })
}
查看索引清单
rs01 [direct: primary] test> db.addresses.getIndexes()
[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{ v: 2, key: { borough: 1 }, name: 'borough_1' }
]
再次查询测试
rs01 [direct: primary] test> db.addresses.find({"borough":"abcd"}).explain()['queryPlanner']['winningPlan']
{
stage: 'FETCH',
inputStage: {
stage: 'IXSCAN',
keyPattern: { borough: 1 },
indexName: 'borough_1',
isMultiKey: false,
multiKeyPaths: { borough: [] },
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: { borough: [ '["abcd", "abcd"]' ] }
}
}
可以看到执行计划变成了 IXSCAN 可以利用到索引了。
TIPS:
隐藏一个索引,可以使用索引名的写法,也可以使用具体的列的写法:
db.restaurants.hideIndex( { borough: 1, ratings: 1 } ); // Specify the index key specification document 列出相关列的写法
db.restaurants.hideIndex( "borough_1_ratings_1" ); // Specify the index name 指定索引名的写法
对于一个已存在的索引,将它改为hidden属性。
db.addresses.hideIndex( "borough_1" ); 或者 db.addresses.hideIndex( { borough: 1 } );
发布者:admin,转转请注明出处:http://www.yc00.com/web/1747524909a4647694.html
评论列表(0条)