MongoDB查询(范围过滤器+排序)性能调整

时间:2019-03-21 11:35:11

标签: mongodb mongodb-indexes

我有一个Mongo集合,其中包含以下格式的数百万个文档:

{
    "_id" : ObjectId("5ac37fa989e00723fc4c7746"),
    "group-number" : NumberLong(128125089),
    "date" : ISODate("2018-04-03T13:20:41.193Z")
}

我想检索按' group-numbe r'排序的2个日期(' date ')之间的文档。因此,我正在执行这种查询:

db.getCollection('group').find({date:{$gt:new Date(1491372960000),$lt:new Date(1553152560000)}}).sort({"group-number":1})

根据https://blog.mlab.com/2012/06/cardinal-ins/,似乎MongoDB在不按等效值查询但具有 range 值时(如我的情况)更好以相反的顺序创建索引(首先是排序字段,然后是过滤字段)。 确实,索引db.group.createIndex({"group-number":1,"date":1});的使用效果最好。但是仍然需要太长时间。在相同情况下超过40秒。

根据 explain()结果,确实使用了上述索引。

"winningPlan" : {
            "stage" : "FETCH",
            "filter" : {
                "$and" : [ 
                    {
                        "date" : {
                            "$lt" : ISODate("2019-03-21T07:16:00.000Z")
                        }
                    }, 
                    {
                        "date" : {
                            "$gt" : ISODate("2017-04-05T06:16:00.000Z")
                        }
                    }
                ]
            },
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "group-number" : 1.0,
                    "date" : 1.0
                },
                "indexName" : "group-number_1_date_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "group-number" : [],
                    "date" : []
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "group-number" : [ 
                        "[MinKey, MaxKey]"
                    ],
                    "date" : [ 
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        }

如何提高性能?我一定想念一些东西...

1 个答案:

答案 0 :(得分:0)

我将以相反的方式建立索引:db.createIndex({date: 1, 'group-number': 1})。仅仅因为您实际上是通过date字段进行查询,所以它应该在复合索引中排在第一位。您仅使用group-number进行排序。这样,WiredTiger可以更轻松地在BTree中查找必要的文档。