我正在依靠拥有超过1亿份文档的集合。
我的查询是:
{
"domain": domain,
"categories" : "buzz",
"visit.timestamp" : { "$gte": date_from, "$lt": date_to },
}
我只预测_id
。
我有一些索引,例如:
{ "visit.timestamp": -1 }
和复合索引如:
{ "visit.timestamp": -1, "domain": 1, "categories" : 1 }
基于每个例子,最后30天的计数给出约30秒的结果。
explain()
向我显示查询使用最简单的索引:{ "visit.timestamp": -1 }
所以我试图以其他顺序强制复合索引:
{ "categories" : 1, "domain": 1, "visit.timestamp": -1 }
{ "domain": 1, "categories" : 1, "visit.timestamp": -1 }
然后,查询使用其中一个,但结果需要更长时间:第一种情况下约为60秒,而另一种情况则超过241秒!
注1:与聚合框架的结果相同,但这并不奇怪。
注2:“visit.timestamp”是ISODate
。每份文件都比前一份文件更新。
注3:该计数返回约140万份文件(约为1.05亿),但检查了12百万份文件(见下文)。
问题:
1 /我不明白为什么在使用完全覆盖它的索引时查询需要更长的时间。你有解释吗?
2 /您是否有任何提示可以改善此查询的响应时间?
explain()
显示查询已查看:
"totalKeysExamined": 12628476,
"totalDocsExamined": 12628476,
因为,据我所知,索引仅涵盖日期索引visit.timestamp
,因此必须检查时间范围内的所有文档。
答案 0 :(得分:1)
第二个问题:
如果索引不适合RAM,会发生什么?
当索引太大而无法放入RAM时,MongoDB必须读取 来自磁盘的索引,这是一个比读取慢得多的操作 内存。请记住,当服务器具有RAM时,索引适合RAM 可用于索引以及working set的其余部分。
在某些情况下,索引不需要完全适合RAM。对于 详情请参阅Indexes that Hold Only Recent Values in RAM。
第一个问题:
也许你的索引不适合RAM。使其复合可能会增加磁盘的I / O操作次数。我不是MongoDB专家。