Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 虽然设置了索引,但简单MongoDB查询速度非常慢_Performance_Mongodb_Indexing - Fatal编程技术网

Performance 虽然设置了索引,但简单MongoDB查询速度非常慢

Performance 虽然设置了索引,但简单MongoDB查询速度非常慢,performance,mongodb,indexing,Performance,Mongodb,Indexing,我有一个MongoDB收藏,里面有大约1亿份文档 文档基本上如下所示: _id : ObjectId("asd1234567890") _reference_1_id : ObjectId("fgh4567890123") _reference_2_id : ObjectId("jkl7890123456") name : "Test1" id : "4815162342" created_time : Date( 1

我有一个MongoDB收藏,里面有大约1亿份文档

文档基本上如下所示:

_id             : ObjectId("asd1234567890")
_reference_1_id : ObjectId("fgh4567890123")
_reference_2_id : ObjectId("jkl7890123456")
name            : "Test1"
id              : "4815162342"
created_time    : Date( 1331882436000 )
_contexts       : ["context1", "context2"]
...
设置了一些索引,下面是db.mycoll.getIndexes()的输出

当我执行如下查询时

db.mycoll.find({"_reference_2_id" : ObjectId("jkl7890123456")})
不管是否有结果,它都需要一个多小时(!)才能完成。 有什么想法吗

更新: 下面是我们的输出

db.mycoll.find({"_reference_2_id" : ObjectId("jkl7890123456")}).explain();
看起来像:

{
"cursor" : "BasicCursor",
"nscanned" : 99209163,
"nscannedObjects" : 99209163,
"n" : 5007,
"millis" : 5705175,
"nYields" : 17389,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {

}
}

我会尝试在
\u reference\u 2\u id
上设置一个非唯一索引,因为目前,我怀疑您将执行相当于完整表扫描的操作,因为即使索引包含
\u reference\u 2\u id
,它们也不会被使用(请参见)。

您没有mongo将自动用于该操作的任何索引,所以它在做一个全表扫描

如中所述

如果查询中不存在[索引的]第一个键,则只有在明确提示的情况下才会使用索引

为什么

如果您在a、b上有一个索引-并且您仅通过
a
进行搜索-将自动使用索引。这是因为它是索引的开始(这很快就能完成),db可以忽略其余的索引值

仅通过
b
进行搜索时,a,b上的索引效率低下,因为它不允许使用“从thisfixedstring开始”的索引搜索

因此,要么:

  • 在查询中包含_reference_1_id(可能不相关)
  • 或者在_reference_2_id上添加索引(如果经常按字段查询)
  • 或者使用提示
提示

现在可能是你的最低成本选择

添加查询提示以强制使用
\u reference\u 1\u id\u 1\u reference\u 2\u id\u 1\u id\u 1
索引。这可能比完整表扫描快得多,但仍然比以查询中使用的字段开头的索引慢得多

i、 e

惠, 我在同等数量的数据上解决了同样的问题。在文档中,有人写道,带有索引的查询必须适合ram。我认为情况并非如此,查询必须进行大量磁盘访问才能首先检索索引,然后获取值。在您的情况下,直接收集读取将更快


EV.

查看explain()的输出(请参见更新的问题),您是对的,我正在进行一次不使用索引的全表扫描。但为什么会这样呢?我在MongoDB文档中看不到关于这方面的任何信息。太好了,非常感谢您的详细回答!实际上,我可以包含_reference_1_id,因此我甚至不需要提示索引。
{
"cursor" : "BasicCursor",
"nscanned" : 99209163,
"nscannedObjects" : 99209163,
"n" : 5007,
"millis" : 5705175,
"nYields" : 17389,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {

}
}
db.mycoll
    .find({"_reference_2_id" : ObjectId("jkl7890123456")})
    .hint("_reference_1_id_1__reference_2_id_1_id_1");