在 MongoDB 中,我有一个文档集合,其中包含一个包含子文档的数组,我想在以下位置建立索引:
{
_id : ObjectId(),
members : [
{ ref : ObjectId().str, ... },
{ ref : ObjectId().str, ... },
...
]
}
索引位于 ref 字段上,因此我可以快速找到在其成员中具有特定“ref”的所有文档:
db.test.ensureIndex({ "members.ref" : 1 });
我注意到,当数组长度超过几千时,将额外的子文档推送到数组的性能会迅速下降。如果我改为在字符串数组上使用索引,则性能不会降低。
以下代码演示了该行为:
var _id = ObjectId("522082310521b655d65eda0f");
function initialize () {
db.test.drop();
db.test.insert({ _id : _id, members : [], memberRefs : [] });
}
function pushToArrays (n) {
var total, err, ref;
total = Date.now();
for (var i = 0; i < n; i++) {
ref = ObjectId().str;
db.test.update({ _id : _id }, { $push : { members : { ref : ref }, memberRefs : ref } });
err = db.getLastError();
if (err) {
throw err;
}
if ((i + 1) % 1000 === 0) {
print("pushed " + (i + 1));
}
}
total = Date.now() - total;
print("pushed " + n + " in " + total + "ms");
}
initialize();
pushToArrays(5000);
db.test.ensureIndex({ "members.ref" : 1 });
pushToArrays(10);
db.test.dropIndexes();
db.test.ensureIndex({ "memberRefs" : 1 });
pushToArrays(10);
db.test.dropIndexes();
例如,在我的机器上使用 MongoDB 2.4.6,我看到以下时间用于在长度为 5000 的数组上推送 10 个元素:
- “members.ref”的索引:37272ms
- “memberRefs”索引:405ms
That difference seems unexpected. Is this a problem with MongoDB or my use of the multikey index? Is there a recommended way of handling this? Thanks.