我有一个查询,它在"_id“上使用复合索引和排序。复合索引在索引的末尾有"_id“,在我向查询添加$gt子句之前,它工作得很好。
即初始查询
db.colletion.find({"field1": "blabla", "field2":"blabla"}).sort({_id:1}
后续查询
db.colletion.find({"field1": "blabla", "field2":"blabla", _id:{$gt:ObjetId('...')}}).sort({_id:1}
我注意到的是,有些时候我的复合索引没有被使用。相反,Mongo使用缺省值
"BtreeCursor _id_"
为了避免这种情况,我向光标添加了一个提示。我想知道这是否会对性能产生影响?因为集合已经有了索引,但是Mongo决定使用一个不同的索引来服务于我的查询。
我注意到的一件事是,当我使用提示时
"cursor" : "QueryOptimizerCursor", "n" : 1, "nscannedObjects" : 2, "nscanned" : 2, "nscannedObjectsAllPlans" : 2, "nscannedAllPlans" : 2, "scanAndOrder" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "server" : "aaa-VirtualBox:27017", "filterSet" : false
耗时更快>毫秒
而不是在没有提示的情况下提供相同的查询
"cursor" : "BtreeCursor _id_", "isMultiKey" : false, "n" : 1, "nscannedObjects" : 1, "nscanned" : 1, "nscannedObjectsAllPlans" : 3, "nscannedAllPlans" : 3, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 3,
在使用我忽略的提示时有没有权衡?在大型集合上,这一性能是否相同?
发布于 2017-03-18 21:34:13
您可以指定您创建的复合索引吗?我没有太多的名声,所以我不能在评论中问这个问题。但我对你的问题有一个可能的答案。Mongo使用了一个名为“Equality Sort-Range”的属性,它的行为方式有所不同。考虑以下情况-您有几个具有字段{name: string,pin: 6位数字,ssn: 9位数字}的文档,您有两个索引- {name : 1,pin : 1,SSN :1},第二个索引是{name : 1,ssn : 1,pin : 1}现在考虑以下查询:
db.test.find({name: "XYZ", pin: 123456"}).sort({ssn: 1})这个查询将使用第一个索引,因为我们有一个复合索引在继续。名称、pin、ssn都是continuation.db.test.find({name: "XYZ", pin: {$gt :123456"}}).sort({ssn: 1})格式,您将期望在此查询中使用第一个索引。但令人惊讶的是,这个查询将使用秒索引,因为它在pin上有一个范围操作。Equality-sort-range属性表示查询规划器将在字段上使用索引,该索引更好地服务于"equality-sort-range“。第二个查询的范围在pin上,因此将使用第二个索引,而第一个查询在所有字段上具有相等,因此将使用第一个索引。
https://stackoverflow.com/questions/42871998
复制相似问题