MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

MongoDB - L'index n'est pas utilisé lors du tri et de la limitation des requêtes étendues

Le problème est qu'aucun de vos index n'aide réellement avec la requête triée. C'est la raison du nombre élevé d'objets scannés et de la présence de SORT_KEY_GENERATOR stage (tri en mémoire, limité à 32 Mo).

La requête non triée, en revanche, peut utiliser soit la { category: 1, _id: 1 } ou { category: 1, _id: 1, sticky: 1, lastPostAt: 1 } index. Notez qu'il est parfaitement valide d'utiliser l'un ou l'autre, car l'un contient le préfixe de l'autre. Voir Préfixes pour plus de détails.

MongoDB find() Les requêtes utilisent généralement un seul index, donc un seul index composé doit répondre à tous les paramètres de votre requête. Cela inclurait à la fois les paramètres de find() et sort() .

Une bonne description de la manière dont votre index doit être créé est disponible dans Optimisation des index composés MongoDB. Prenons le point principal de l'article, où l'ordre de l'index composé devrait être equality --> sort --> range :

Votre requête "forme" est :

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

Nous voyons que :

  • category:... est l'égalité
  • sticky:-1, lastPostAt:-1, _id:1 est trier
  • _id: {$gt:...} est plage

L'index composé dont vous avez besoin est :

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

D'où le plan gagnant du explain() le résultat de votre requête avec l'index ci-dessus indique :

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

Notez que le plan gagnant ne contient pas de SORT_KEY_GENERATOR organiser. Cela signifie que l'index peut être pleinement utilisé pour répondre à la requête triée.