Мне нужно решить проблему с производительностью mongodb find. В частности, мне нужно, чтобы направление сканирования индекса было противоположным тому, что предлагалось планировщику запросов.
Описание проблемы:
1) Давайте получим большую коллекцию со структурой всего с двумя полями
- отметка времени (проиндексированная)
- имя (не индексируется, не присваивается всем документам)
2) Я хочу получить самый последний (в соответствии с меткой времени) документ с присвоенным «именем»
3) Я знаю, с чего начать поиск (например, у меня есть документы 1e7, и я знаю, что последний документ с присвоенным именем находится за определенной временной отметкой (например, «2018-03-06 18: 45: 00.000Z»)
Я использую следующий запрос:
db.getCollection('mycoll').find({$and:[{'timestamp': {$gte: ISODate('2018-03-06 18:45')}}, {'name': {$exists:true}}]})
.sort({'timestamp':-1})
.limit(1)
Проблема заключается в том, что планировщик запросов по умолчанию решает отсканировать запрос метки времени в обратном направлении, и он очень медленный, поскольку результат близок к началу. Смотрите вывод планировщика:
{
"stage" : "LIMIT",
"limitAmount" : 1,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"name" : {
"$exists" : true
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"timestamp" : 1
},
"indexName" : "timestamp_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"timestamp" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"timestamp" : [
"[new Date(9223372036854775807), new Date(1520361900000)]"
]
}
}
}
См. «направление»: «назад» в плане запроса.
Вопрос : Есть ли способ заставить направление поиска переместиться вперед?
Примечание. Я тестировал с помощью .hint ({$ natural: 1}), но он совершенно бесполезен.