MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB – Index wird beim Sortieren und Einschränken der Bereichsabfrage nicht verwendet

Das Problem ist, dass keiner Ihrer Indizes tatsächlich bei der sortierten Abfrage hilft. Dies ist der Grund für die hohe Anzahl gescannter Objekte und das Vorhandensein von SORT_KEY_GENERATOR Stufe (In-Memory-Sortierung, begrenzt auf 32 MB).

Die unsortierte Abfrage hingegen kann entweder den { category: 1, _id: 1 } verwenden oder { category: 1, _id: 1, sticky: 1, lastPostAt: 1 } Indizes. Beachten Sie, dass es vollkommen gültig ist, eines von beiden zu verwenden, da eines das Präfix enthält des anderen. Weitere Einzelheiten finden Sie unter Präfixe.

MongoDB find() Abfragen verwenden normalerweise nur einen Index, daher sollte ein einzelner zusammengesetzter Index alle Parameter Ihrer Abfrage berücksichtigen. Dies würde beide Parameter von find() beinhalten und sort() .

Eine gute Beschreibung, wie Ihr Index erstellt werden sollte, finden Sie unter Optimieren zusammengesetzter MongoDB-Indizes. Nehmen wir den Hauptpunkt des Artikels, wo die zusammengesetzte Indexreihenfolge Gleichheit --> Sortierung --> Bereich sein sollte :

Ihre Suchanfrage "Form" lautet:

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

Wir sehen das:

  • category:... ist Gleichheit
  • sticky:-1, lastPostAt:-1, _id:1 ist sortieren
  • _id: {$gt:...} ist Bereich

Der zusammengesetzte Index, den Sie benötigen, lautet also:

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

Wo der Gewinnerplan des explain() ist Die Ausgabe Ihrer Abfrage mit dem obigen Index zeigt:

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

Beachten Sie, dass der Gewinnerplan keinen SORT_KEY_GENERATOR enthält Bühne. Das bedeutet, dass der Index vollständig genutzt werden kann, um auf die sortierte Anfrage zu antworten.