我对索引查询的性能降低有疑问。我有一个由两个字段'COLOR'和'FLAVOR'索引的集合。该系列相当沉重,重达27M的文件。当我分别使用每个字段查询集合时,我得到更快的回报
collection.find({'COLOR': 'BLUE'}).count()
collection.find({'FLAVOR': 'SWEET'}).count()
当我将这些字段组合到一个查询中时,性能会大幅下降。本质上,查询无限期地运行(没有错误)。
collection.find({'COLOR': 'BLUE’},{'FLAVOR': 'SWEET'}).count()
为什么会发生这种情况?
答案 0 :(得分:3)
性能的巨大差异可能是由于需要将文件从磁盘加载到内存中。假设您的组合查询写得不正确,并且您的意思是查询等同于
db.collection.count({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" })
即。计算COLOR
为"BLUE"
且FLAVOR
为"SWEET"
的文档数量,MongoDB将选择COLOR
和FLAVOR
之一的索引帮助完成查询。选择将基于经验比较两者的表现;为这个答案选择哪一个并不重要,因此我们假设查询使用索引{ "COLOR" : 1 }
并与
db.collection.count({ "COLOR" : "BLUE" })
后一个查询只需要查看"COLOR" : "BLUE"
索引BTree节点中的文档指针数。前一个查询将使用BTree查找"COLOR" : "BLUE"
所在的文档,但必须加载每个文档并检查是否"FLAVOR" : "SWEET"
。 FLAVOR
上的索引无法用于后一种操作,因为它会将FLAVOR
值映射到文档,而不是相反。
您无法直接看到这种情况,因为.count
会返回一个整数,但是当您比较覆盖的查询时,它几乎完全相同
db.collection.find({ "COLOR" : "BLUE" }, { "_id" : 0, "COLOR" : 1 })
带有查询
db.collection.find({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" }, { "_id" : 0, "COLOR" : 1 })
我建议您使用.explain
同时尝试这两个查询并比较n
,nscanned
和nscannedObjects
。
您可以使用db.collection.count({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" })
上的复合索引生成计数{ "COLOR" : 1, "FLAVOR" : 1 }
,如评论中所述。