我有一个大约8000万个文档的集合,每个文档在tags
字段中存储一个标记数组,例如:
{text: "blah blah blah...", tags: ["car", "auto", "automobile"]}
字段tags
是有索引的,所以像这样的查询几乎是即时的:
db.documents.find({tags:"car"})
但是,以下查询都非常慢,需要几分钟才能完成:
db.documents.find({tags:{$all:["car","phone"]}})
db.documents.find({tags:{$in:["car","auto"]}})
即使数组只有一项,问题仍然存在:
db.documents.find({tags:{$all:["car"]}}) //very slow too
我认为$all和$in应该能够非常快地工作,因为tags
是索引的,但显然情况并非如此。为什么?
发布于 2012-10-07 00:49:02
事实证明,这是MongoDB中的一个已知错误,该错误在2.2版本中尚未修复
使用$all
搜索多个条目时,MongoDB不会执行索引交集。只使用索引查找数组中的第一项,并对所有匹配的文档执行扫描以过滤结果。
例如,在查询db.documents.find({tags:{$all:["car","phone"]}})
中,需要检索和扫描所有包含标记"car“的文档。由于有问题的集合包含超过10万个标记为"car“的文档,因此速度减慢并不令人惊讶。
更糟糕的是,MongoDB甚至不执行简单的优化,即在$all数组中选择代表最少的项进行索引查找。即使有100000个标记为"car“的文档和10个标记为"phone”的文档,MongoDB仍需要扫描100000个文档才能为{$all:["car", "phone"]}
返回结果
发布于 2012-11-14 18:34:41
我只想补充一句,$in速度很快。事实上,只要有一个条件或关键字,$in就等同于$all,但$in很快,$all很慢。
所以使用$in。
https://stackoverflow.com/questions/12760879
复制相似问题