mongoDB中的_id_hashed索引是什么?

时间:2013-09-04 02:46:46

标签: mongodb mongodb-indexes

我通过哈希_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

4 个答案:

答案 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)

散列索引由分片集合来要求,更确切地说,散列索引由分片平衡器来要求,以直接基于散列值查找文档, 普通的查询操作即使在共享集合上也不需要索引就成为哈希索引。