sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB:el índice no se usa al ordenar y limitar la consulta a distancia

El problema es que ninguno de sus índices realmente ayuda con la consulta ordenada. Esta es la razón de la gran cantidad de objetos escaneados y la presencia de SORT_KEY_GENERATOR etapa (clasificación en memoria, limitada a 32 MB).

La consulta no ordenada, por otro lado, puede usar la categoría { category: 1, _id: 1 } o { category: 1, _id: 1, sticky: 1, lastPostAt: 1 } índices Tenga en cuenta que es perfectamente válido usar cualquiera de los dos, ya que uno contiene el prefijo del otro. Consulte Prefijos para obtener más detalles.

MongoDB find() las consultas generalmente usan solo un índice, por lo que un solo índice compuesto debe atender todos los parámetros de su consulta. Esto incluiría ambos parámetros de find() y sort() .

Una buena descripción de cómo se debe crear su índice está disponible en Optimización de índices compuestos de MongoDB. Tomemos el punto principal del artículo, donde el orden del índice compuesto debería ser igualdad --> ordenar --> rango :

Su consulta "forma" es:

db.collection.find({category:..., _id: {$gt:...}})
             .sort({sticky:-1, lastPostAt:-1, _id:1})
             .limit(25)

Vemos que:

  • category:... es igualdad
  • sticky:-1, lastPostAt:-1, _id:1 es ordenar
  • _id: {$gt:...} es rango

Entonces el índice compuesto que necesitas es:

{category:1, sticky:-1, lastPostAt:-1, _id:1}

Donde el plan ganador del explain() el resultado de su consulta con el índice anterior muestra:

"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')]"
            ]
          }
        }
      }
    }

Tenga en cuenta que el plan ganador no contiene un SORT_KEY_GENERATOR escenario. Esto significa que el índice se puede utilizar por completo para responder a la consulta ordenada.