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

Wie man einen zusammengesetzten Index in Mongodb aufbaut

Das sind viele Fragen in einem Beitrag;) Lassen Sie mich sie in einer praktischen Reihenfolge durchgehen :

  • Jede Abfrage kann höchstens einen Index verwenden (mit Ausnahme von Top-Level-$or-Klauseln und dergleichen). Dies schließt jegliche Sortierung ein.
  • Aus den oben genannten Gründen benötigen Sie für Ihr Problem auf jeden Fall einen zusammengesetzten Index und keine separaten Indexe pro Feld.
  • Felder mit niedriger Kardinalität (also Felder mit sehr wenigen eindeutigen Werten in Ihrem Datensatz) sollten normalerweise nicht im Index enthalten sein, da ihre Selektivität sehr begrenzt ist.
  • Die Reihenfolge der Felder in Ihrem zusammengesetzten Index ist wichtig, ebenso wie die relative Richtung der einzelnen Felder in Ihrem zusammengesetzten Index (z. B. "{name:1, age:-1}"). Auf mongodb.org gibt es eine Menge Dokumentation über zusammengesetzte Indizes und Indexfeldrichtungen, daher werde ich hier nicht alles wiederholen.
  • Sortierungen verwenden den Index nur, wenn sich das Sortierfeld im Index befindet und das Feld im Index direkt nach dem letzten Feld ist, das zur Auswahl der Ergebnismenge verwendet wurde. In den meisten Fällen wäre dies das letzte Feld des Indexes.

Sie sollten den Status also überhaupt nicht in Ihren Index aufnehmen, da der Indexwalk, nachdem er die überwiegende Mehrheit der Dokumente basierend auf Feldern mit höherer Kardinalität eliminiert hat, in den meisten Fällen höchstens 2-3 Dokumente übrig hat, was durch einen Statusindex kaum optimiert wird (zumal Sie erwähnt haben, dass diese 2-3 Dokumente sehr wahrscheinlich sowieso den gleichen Status haben).

Nun, die letzte Anmerkung, die in Ihrem Fall relevant ist, ist, dass bei der Verwendung von Bereichsabfragen (und Sie sind) der Index sowieso nicht zum Sortieren verwendet wird. Sie können dies überprüfen, indem Sie sich den „scanAndOrder“-Wert Ihres explain() ansehen, nachdem Sie Ihre Abfrage getestet haben. Wenn dieser Wert vorhanden und wahr ist, bedeutet dies, dass die Ergebnismenge im Speicher sortiert wird (Scan und Reihenfolge), anstatt den Index direkt zu verwenden. Dies lässt sich in Ihrem konkreten Fall nicht vermeiden.

Ihr Index sollte also :

lauten
db.posts.ensureIndex({start:1, end:1})

und Ihre Abfrage (Reihenfolge nur aus Gründen der Übersichtlichkeit geändert, der Abfrageoptimierer führt Ihre ursprüngliche Abfrage über denselben Ausführungspfad aus, aber ich ziehe es vor, indizierte Felder zuerst und in der richtigen Reihenfolge zu platzieren):

db.posts.find({start: {$lt: today}, end: {$gt: today}, status: {$gte:0}}).sort({sortOrder:1})