我通过哈希_id对我的mongoDB群集进行了分片。我检查了索引大小,有一个_id_hashed索引占用了很多空间:
"indexSizes" : { "_id_" : 14060169088, "_id_hashed" : 9549780576 },
mongoDB手册说,如果您对一个集合进行分片,则会创建一个分片键的索引。我猜这就是_id_hashed索引出现的原因。
我的问题是:如果我只通过_id字段查询文档,那么_id_hashed索引是什么?我可以删除吗?因为它需要太多的空间。
PS: 似乎mongoDB在查询时使用_id索引,而不是_id_hashed索引。 查询的执行计划:
"clusteredType" : "ParallelSort", "shards" : { "rs1/192.168.62.168:27017,192.168.62.181:27017" : [ { "cursor" : "BtreeCursor _id_", "isMultiKey" : false, "n" : 0, "nscannedObjects" : 0, "nscanned" : 1, "nscannedObjectsAllPlans" : 0, "nscannedAllPlans" : 1, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "indexBounds" : { "start" : { "_id" : "spiderman_task_captainStatus_30491467_2387600" }, "end" : { "_id" : "spiderman_task_captainStatus_30491467_2387600" } }, "server" : "localhost:27017" } ] }, "cursor" : "BtreeCursor _id_", "n" : 0, "nChunkSkips" : 0, "nYields" : 0, "nscanned" : 1, "nscannedAllPlans" : 1, "nscannedObjects" : 0, "nscannedObjectsAllPlans" : 0, "millisShardTotal" : 0, "millisShardAvg" : 0, "numQueries" : 1, "numShards" : 1, "indexBounds" : { "start" : { "_id" : "spiderman_task_captainStatus_30491467_2387600" }, "end" : { "_id" : "spiderman_task_captainStatus_30491467_2387600" } }, "millis" : 574
答案 0 :(得分:2)
MongoDB使用基于范围的分片方法。如果选择使用基于散列的分片,则必须在分片键上具有散列索引,并且不能删除它,因为它将用于确定要用于任何后续查询的分片(请注意,有一个打开的票证允许您删除_id索引一旦哈希索引被允许是唯一的SERVER-8031)。
至于为什么查询似乎使用_id索引而不是_id_hashed索引 - 我运行了一些测试,我认为优化器正在选择_id索引,因为它是唯一的并且会产生更有效的计划。如果您对另一个具有预先存在的唯一索引的键进行分片,则可以看到类似的行为。
答案 1 :(得分:0)
如果您在散列_id上进行分片,那么这就是创建的索引类型。
当你执行sh.shardCollection( 'db.collection', { _id:"hashed" } )
时,你告诉它你想使用_id的哈希作为分片键,需要 _id
上的哈希索引。
所以,不,你不能放弃它。
答案 2 :(得分:0)
文档详细详细说明了散列索引是什么让我困惑如何阅读文档,但不知道散列索引的用途。
该索引主要用于阻止分片键中的热点,这些热点可能与其读/写不均匀分布。
想象一下_id
字段,它是一个不断增加的范围,所有新的_id
都将在之后,这意味着你总是在集群的末尾写字,创造一个热点
至于阅读,你只阅读最新的文件是很常见的,因此这意味着_id
键的上限是唯一一个用于写入和写入热点的键。在群集的较高范围内,而群集的其余部分只是闲置在那里。
哈希索引采用这个错误的分片键并以这样的方式对其进行哈希处理,这意味着它不会增加,而是会为读取和写入创建一个均匀分布的数据集,希望将整个集合用于操作
我强烈建议你不要删除它。
答案 3 :(得分:0)
散列索引由分片集合来要求,更确切地说,散列索引由分片平衡器来要求,以直接基于散列值查找文档, 普通的查询操作即使在共享集合上也不需要索引就成为哈希索引。