Mongodb 多索引搜索性能下降
Mongodb multi index search reduced performance
我对索引查询性能下降有疑问。我有一个由“COLOR”和“FLAVOR”两个字段索引的集合。该集合相当庞大,有 2700 万份文件。当我分别使用每个字段查询集合时,我得到了更快的回报
collection.find({'COLOR': 'BLUE'}).count()
collection.find({'FLAVOR': 'SWEET'}).count()
当我将这些字段合并到一个查询中时,性能会大幅下降。本质上,查询会无限期地运行(w/o 错误)。
collection.find({'COLOR': 'BLUE’},{'FLAVOR': 'SWEET'}).count()
知道为什么会这样吗?
性能上的巨大差异可能是由于需要将文档从磁盘加载到内存中。假设你的组合查询写错了,你的意思是查询等同于
db.collection.count({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" })
即统计 COLOR
为 "BLUE"
且 FLAVOR
为 "SWEET"
的文档数,MongoDB 将选择 COLOR
和 [= 上的索引之一16=] 来帮助完成查询。将根据经验比较两者的性能来做出选择;这个答案选择哪个并不重要,所以我们假设查询使用索引 { "COLOR" : 1 }
并与
进行比较
db.collection.count({ "COLOR" : "BLUE" })
后面的查询只需要查看"COLOR" : "BLUE"
索引BTree节点中文档指针的数量。前一个查询将使用 BTree 查找 "COLOR" : "BLUE"
处的文档,但随后必须加载每个文档并检查是否 "FLAVOR" : "SWEET"
。 FLAVOR
上的索引不能用于后一个操作,因为它从 FLAVOR
值映射到文档,而不是相反。
你不能直接看到这种情况发生,因为 .count
returns 是一个整数,但是当你比较覆盖查询时,它几乎是一样的事情发生
db.collection.find({ "COLOR" : "BLUE" }, { "_id" : 0, "COLOR" : 1 })
与查询
db.collection.find({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" }, { "_id" : 0, "COLOR" : 1 })
我建议使用 .explain
尝试这两个查询并比较 n
、nscanned
和 nscannedObjects
.
您可以在 { "COLOR" : 1, "FLAVOR" : 1 }
上使用复合索引来生成计数 db.collection.count({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" })
,如评论中所述。
我对索引查询性能下降有疑问。我有一个由“COLOR”和“FLAVOR”两个字段索引的集合。该集合相当庞大,有 2700 万份文件。当我分别使用每个字段查询集合时,我得到了更快的回报
collection.find({'COLOR': 'BLUE'}).count()
collection.find({'FLAVOR': 'SWEET'}).count()
当我将这些字段合并到一个查询中时,性能会大幅下降。本质上,查询会无限期地运行(w/o 错误)。
collection.find({'COLOR': 'BLUE’},{'FLAVOR': 'SWEET'}).count()
知道为什么会这样吗?
性能上的巨大差异可能是由于需要将文档从磁盘加载到内存中。假设你的组合查询写错了,你的意思是查询等同于
db.collection.count({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" })
即统计 COLOR
为 "BLUE"
且 FLAVOR
为 "SWEET"
的文档数,MongoDB 将选择 COLOR
和 [= 上的索引之一16=] 来帮助完成查询。将根据经验比较两者的性能来做出选择;这个答案选择哪个并不重要,所以我们假设查询使用索引 { "COLOR" : 1 }
并与
db.collection.count({ "COLOR" : "BLUE" })
后面的查询只需要查看"COLOR" : "BLUE"
索引BTree节点中文档指针的数量。前一个查询将使用 BTree 查找 "COLOR" : "BLUE"
处的文档,但随后必须加载每个文档并检查是否 "FLAVOR" : "SWEET"
。 FLAVOR
上的索引不能用于后一个操作,因为它从 FLAVOR
值映射到文档,而不是相反。
你不能直接看到这种情况发生,因为 .count
returns 是一个整数,但是当你比较覆盖查询时,它几乎是一样的事情发生
db.collection.find({ "COLOR" : "BLUE" }, { "_id" : 0, "COLOR" : 1 })
与查询
db.collection.find({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" }, { "_id" : 0, "COLOR" : 1 })
我建议使用 .explain
尝试这两个查询并比较 n
、nscanned
和 nscannedObjects
.
您可以在 { "COLOR" : 1, "FLAVOR" : 1 }
上使用复合索引来生成计数 db.collection.count({ "COLOR" : "BLUE", "FLAVOR" : "SWEET" })
,如评论中所述。