对不起我的英语,我需要mongodb索引方面的帮助。我有一个上限集合(大小:10GB),其中有一些字段用于我的应用程序日志。示例结构:Logs[_id,userId,sum,type,time,response,request]。我创建了复合索引:[userId,time,type]。我得到两个数组是按userId对今天的记录进行分组的,其中"type"是"null"answers"1"。我的两个查询示例:
$group = array(
array(
'$match' => array(
'userId' => $userId,
'time' => array(
'$gt' => date("Y-m-d")
),
'type' => array('$ne' => null)
)
),
array(
'$group' => array(
"_id" => '$userId',
"total" => array('$sum' => '$sum'),
"count" => array('$sum' => 1)
),
)
);
$results = $collections->aggregate($group);
$group = array(
array(
'$match' => array(
'userId' => $userId,
'time' => array(
'$gt' => date("Y-m-d")
),
'type' => 1
)
),
array(
'$group' => array(
"_id" => '$userId',
"count" => array('$sum' => 1)
),
)
);
$results2 = $collections->aggregate($group);
如果当前用户今天收集的文档超过100000个,那么我的查询速度非常慢(超过10秒)。请给我一些关于创建正确索引的建议:)谢谢。
根据您发布的解释,使用了正确的索引(BtreeCursor
),只使用了索引(即,它是一个覆盖索引查询-indexOnly
为true),在这种情况下没有匹配任何内容(n = 0
)。因此,尽管$ne
作为第一个例子中的子句并不是很有效,但这一切都得到了普遍的检验。
然而,基于解释的主要问题可能是索引似乎没有完全存储在内存中。列出了13个收益率,像这样的查询产生收益率的最常见原因是它必须故障到磁盘才能分页。由于如前所述,它只使用索引,这些收益率意味着索引的磁盘故障,因此表明整个索引不在内存中。
如果您在这之后立即重新运行查询,它应该会更快(假设索引实际上可以放入可用内存),因为索引在第一次运行时已经被分页。如果它在第二次运行时仍然很慢,并且显示出收益率,那么您要么没有足够的内存将索引保存在内存中,要么有其他东西正在将其从内存中逐出,并且您实际上存在导致性能问题的内存争用。