O problema é que nenhum de seus índices realmente ajuda com a consulta classificada. Esta é a razão para o alto número de objetos verificados e a presença de
SORT_KEY_GENERATOR
stage (classificação na memória, limitada a 32 MB). A consulta não classificada, por outro lado, pode usar a
{ category: 1, _id: 1 }
ou { category: 1, _id: 1, sticky: 1, lastPostAt: 1 }
índices. Observe que é perfeitamente válido usar qualquer um, pois um contém o prefixo do outro. Consulte Prefixos para obter mais detalhes. MongoDB
find()
consultas normalmente usam apenas um índice, portanto, um único índice composto deve atender a todos os parâmetros de sua consulta. Isso incluiria os parâmetros de find()
e sort()
. Uma boa descrição de como seu índice deve ser criado está disponível em Optimizing MongoDB Compound Indexes. Vamos pegar o ponto principal do artigo, onde a ordenação do índice composto deve ser igualdade --> classificação --> intervalo :
Sua consulta "forma" é:
db.collection.find({category:..., _id: {$gt:...}})
.sort({sticky:-1, lastPostAt:-1, _id:1})
.limit(25)
Nós vemos que:
category:...
é igualdadesticky:-1, lastPostAt:-1, _id:1
é classificar_id: {$gt:...}
é intervalo
Então o índice composto que você precisa é:
{category:1, sticky:-1, lastPostAt:-1, _id:1}
Onde o plano vencedor do
explain()
saída de sua consulta com o índice acima mostra:"winningPlan": {
"stage": "LIMIT",
"limitAmount": 25,
"inputStage": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"keyPattern": {
"category": 1,
"sticky": -1,
"lastPostAt": -1,
"_id": 1
},
"indexName": "category_1_sticky_-1_lastPostAt_-1__id_1",
"isMultiKey": false,
"multiKeyPaths": {
"category": [ ],
"sticky": [ ],
"lastPostAt": [ ],
"_id": [ ]
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": 2,
"direction": "forward",
"indexBounds": {
"category": [
"[ObjectId('5a779b31f4fa724121265142'), ObjectId('5a779b31f4fa724121265142')]"
],
"sticky": [
"[MaxKey, MinKey]"
],
"lastPostAt": [
"[MaxKey, MinKey]"
],
"_id": [
"(ObjectId('5a779b5cf4fa724121269be8'), ObjectId('ffffffffffffffffffffffff')]"
]
}
}
}
}
Observe que o plano vencedor não contém um
SORT_KEY_GENERATOR
etapa. Isso significa que o índice pode ser totalmente utilizado para responder à consulta classificada.