MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB - Índice não sendo usado ao classificar e limitar a consulta de alcance


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:... é igualdade
  • sticky:-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.