Weiter zum Inhalt
MongoDB

Best Practices für MongoDB-Indizes: Performance-Tipps & Tricks

Erfahre, wie du MongoDB-Indizes erstellst – plus Tipps und Tricks, um ihre Performance optimal zu nutzen.
Nic Raboy's photo
Nic Raboy
Aktualisiert · 8 Min. lesen

Entdecke KI

ChatGPTClaudePerplexity

Erstelle dein kostenloses Konto

Üben und Lernpfad deinen Fortschritt.

Weiter Mit Google
Durch Klick auf die Schaltfläche akzeptierst du unsere Nutzungsbedingungen, unsere Datenschutzrichtlinie und die Speicherung deiner Daten in den USA.

Wie bei jeder Datenbank sind Indizes auch in MongoDB ein zentraler Bestandteil der Entwicklung. Ohne sie nimmt die Performance mit wachsendem Datenvolumen stetig ab. Mit passenden Indizes bleibt der Datenzugriff auch bei Wachstum performant.

In diesem Artikel schauen wir uns die verschiedenen Index-Typen in MongoDB an, geben dir Tipps aus der Praxis und zeigen, wie du sicherstellst, dass deine Abfragen die erstellten Indizes wirklich nutzen. Wenn du noch in MongoDB einsteigst, empfehlen wir dir den Kurs Introduction to MongoDB.

Wo sind MongoDB-Indizes wichtig – und warum?

Bei Indizes geht es um Performance. Sie entscheiden, ob für eine Abfrage die komplette Collection durchsucht werden muss oder nur ein eng abgegrenzter Teil, der zur Abfrage passt. Bei kleinen Collections ist das kaum spürbar. Aber wenn 100.000 Dokumente vorhanden sind und nur 100 davon zur Abfrage passen, dauert das Durchsuchen aller 100.000 ohne passenden Index deutlich länger.

In MongoDB gibt es zahlreiche Index-Typen:

  • Einzelfeld: Ein Index auf genau einem Feld des Dokuments. Der Standardindex auf dem Feld _id ist ein Einzelfeldindex.
  • Zusammengesetzt: Ein Index über mehrere Felder eines Dokuments. Die Reihenfolge der Felder in Abfrage und Index ist dabei entscheidend.
  • Multikey: Ein Index für Array-Felder.
  • Wildcard: Ein Index für Felder, deren Namen zwischen Dokumenten variieren können. Er ist in der Regel weniger performant als andere Indizes.
  • Geospatial: Ein Index zur Beschleunigung georäumlicher Abfragen mit Längen- und Breitengrad.
  • Gehasht: Ein Index, der sich besonders für Shard-Keys eignet.

Mehr Details zu den Index-Typen findest du in der MongoDB-Dokumentation.

In der Praxis wirst du meist Einzelfeld-, zusammengesetzte oder Multikey-Indizes verwenden – was genau sinnvoll ist, hängt immer von Anwendung, Abfragen und Daten ab.

Indizes sind für alle Datenbankoperationen wichtig, die Dokumente finden müssen. Das gilt nicht nur für find oder findOne. Auch beim Aktualisieren und Löschen nutzt die Datenbank ein Match-Kriterium, um die betroffenen Dokumente zu ermitteln.

Nicht nur find und findOne profitieren von Indizes. Verwendest du $match als erste Stufe in einer Aggregation-Pipeline, beschleunigt ein Index die Ausführung erheblich.

MongoDB-Indexierung: Tipps und Tricks für den Erfolg

Zufällig Indizes anzulegen kann genauso ineffizient sein wie ganz ohne Indizes zu arbeiten. Beachte stattdessen ein paar Grundsätze, um deine Anwendung spürbar effizienter zu machen.

Equality, Sort, Range (ESR) für zusammengesetzte Indizes

Die Faustregel für zusammengesetzte Indizes: Überlege, wie die Felder in deiner Abfrage genutzt werden, und richte den Index nach dem ESR-Best-Practice aus.

Was bedeutet ESR? Kurz erklärt:

  • Equality: Felder, auf die exakt gematcht wird, nicht unscharf. Beispiel: Der exakte Name einer Person in der Abfrage.
  • Sort: Felder, nach denen auf- oder absteigend sortiert wird.
  • Range: Felder, auf die mit Bereichsoperatoren gematcht wird, also kein exakter Wert. Beispiel: $lt oder $gt finden Werte innerhalb eines Bereichs.

Ein Beispiel macht es greifbarer. Betrachte diese Abfrage:

db.employee.find(
	{
		"department": "Developer Relations",
		"salary": {
			"$lt": 80000
		}
	}
).sort(
	{ 
		"name": 1 
	}
);

Hier erfolgt ein Equality-Match auf department, ein Range-Match auf salary und eine Sortierung nach name.

Nach ESR-Regel sähe der Index so aus:

db.employee.createIndex({
	"department": 1,
	"name": 1,
	"salary": 1
});

So vermeidest du In-Memory-Sorts und reduzierst die Suchmenge für eine performante Ausführung.

Covered Queries

Indizes reduzieren allgemein die zu scannende Dokumentenmenge und verbessern so die Performance. Noch schneller wird es mit Covered Queries: Dann liefert der Index alle benötigten Ergebnisse direkt, ohne dass Dokumente in der Collection gelesen werden müssen.

Dafür gelten ein paar Bedingungen, die je nach Anwendung erfüllt sind oder nicht:

  • Match-Kriterien und Sortierung müssen exakt zum Index passen.
  • Auch die in der Projektion angeforderten Felder müssen im Index enthalten sein.
  • Bei Sharding muss der Shard-Key Teil des Index sein.

Was heißt das konkret?

Nehmen wir folgenden Index:

db.department.createIndex({
	"country": 1,
	"salary": 1
});

Wir indexieren nach country und salary. Dann führen wir diese Abfrage aus:

db.department.find(
	{
		"country": "US"
	},
	{
		"country": 1,
		"salary": 1
	}
);

Diese Abfrage mit Projektion nutzt zwar den Index, ist aber keine Covered Query. MongoDB gibt standardmäßig das Feld _id zurück, das in unserem Index fehlt. Wir können also entweder den Index anpassen oder die Abfrage ändern. Wenn wir die Abfrage ändern, sähe sie so aus:

db.department.find(
	{
		"country": "US"
	},
	{
		"country": 1,
		"salary": 1,
		"_id": 0
	}
);

Merke: Für eine Covered Query muss der Index passen und alle angeforderten Felder enthalten. Andernfalls findest du nur Dokumente mithilfe des Index – aber liest sie aus der Collection.

Ob eine Covered Query genutzt wird, kannst du mit dem Argument executionStats in explain prüfen. Entscheidend ist totalDocsExamined. Steht dort 0, handelt es sich um eine Covered Query.

Überflüssige Indizes reduzieren oder entfernen

Indizes sind nicht kostenlos – sie verbrauchen Serverressourcen. Jeder Index muss gepflegt werden und benötigt CPU, RAM und Speicherplatz. Viele Indizes erzeugen Overhead, was auf unterdimensionierten Servern zu höheren Kosten oder geringerer Performance führen kann – nicht nur beim Lesen, sondern auch bei Schreib- und Löschvorgängen, da MongoDB mehr Ressourcen benötigt.

Lege Indizes am besten nur für häufige Abfragen an. Muss die monatliche Auswertung wirklich einen eigenen Index haben? Eher nicht. Die Abfrage, die alle 10 Sekunden läuft? Auf jeden Fall!

Weitere Best Practices zur Indexierung findest du im MongoDB-Blog.

Funktioniert dein MongoDB-Index wirklich?

Nur weil ein Index existiert, heißt das nicht, dass deine Abfrage ihn auch nutzt. In MongoDB kannst du prüfen, welcher Index für eine konkrete Abfrage verwendet wird.

Beispielindex:

db.people.createIndex({
	"name": 1,
	"is_active": 1
});

Wir indexieren die Felder name und is_active. Nun diese Abfrage:

db.people.find({
	"is_active": true
});

Die Abfrage läuft mit oder ohne Index. Auf kleinen Datensätzen ist sie ohnehin schnell. Um zu prüfen, ob der Index genutzt wird, ergänzen wir Folgendes:

db.people.find({
	"is_active": true
}).explain();

Mit explain erhalten wir den Ausführungsplan. Darin könnte Folgendes stehen:

winningPlan: {
	isCached: false,
	stage: 'COLLSCAN',
	filter: { is_active: { '$eq': true } },
	direction: 'forward'
}

Hier wurde ein "COLLSCAN" durchgeführt – der Index wurde also trotz passendem Feld nicht genutzt. Ändern wir die Abfrage so:

db.people.find({
	"name": "Nic Raboy",
	"is_active": true
}).explain();

Jetzt ändert sich das Ergebnis von explain:

winningPlan: {
	isCached: false,
	stage: 'FETCH',
	inputStage: {
		stage: 'IXSCAN',
		keyPattern: { name: 1, is_active: 1 },
		indexName: 'name_1_is_active_1',
		isMultiKey: false,
		multiKeyPaths: { name: [], is_active: [] },
		isUnique: false,
		isSparse: false,
		isPartial: false,
		indexVersion: 2,
		direction: 'forward',
		indexBounds: {
			name: [ '["Nic Raboy", "Nic Raboy"]' ],
			is_active: [ '[true, true]' ]
		}
	}
},

Jetzt wird ein "IXSCAN" verwendet, inklusive Name des genutzten Index, hier name_1_is_active_1. Der Name wurde beim Erstellen automatisch vergeben.

Für update-Operationen funktioniert es ähnlich – nur sitzt die explain-Funktion an einer anderen Stelle.

Eine update-Operation könnte so aussehen:

db.people.explain().update(
    {
        “name”: “Nic Raboy”,
        “Is_active”: true
    },
    {
        “$set”: { “is_active”: false }
    }
);

Beachte: Hier wird explain vor update aufgerufen.

Wenn dein Update den erwarteten Index nutzt, siehst du "IXSCAN" und den Indexnamen. Mehr zu Update-Operationen und Indexen.

Alternativ kannst du den Ausführungsplan auch mit runCommand auf der Datenbank abfragen. Weniger hübsch, aber sehr mächtig – zum Beispiel so:

db.runCommand({
    "explain": {
        "update": "people",
        "updates": [
            {
                "q": { 
                    "name": "Nic Raboy",
                    "is_active": true
                },
                "u": {
                    "$set": { "is_active": false }
                }
            }
        ]
    },
    "verbosity": "allPlansExecution"
});

Das entspricht funktional dem explain bei der Update-Operation.

Wenn du unsicher beim Erstellen von Indizes bist oder ungewöhnlich langsame Abfragen siehst, schau dir die Ausführungsdetails an.

Fazit

Du hast zentrale Best Practices für Indizes in MongoDB kennengelernt. Auch wenn wir nicht jeden Spezialfall abgedeckt haben, hast du jetzt eine solide Basis, um deinen Nutzerinnen und Nutzern beim Arbeiten mit deinen Daten die bestmögliche Performance zu bieten.

Zur Erinnerung die wichtigsten Punkte:

  • Halte dich, wenn möglich, an die Equality–Sort–Range-(ESR)-Regel.
  • Nutze Covered Queries, wenn es deine Anforderungen erlauben.
  • Erstelle nicht wahllos Indizes. Identifiziere die wichtigsten Abfragen und deren Datenvolumen.
  • Verlass dich beim Testen auf den Operator explain und bewerte damit Performance und Index-Nutzung.

Diese Liste ist nicht vollständig. Weitere Faktoren können eine Rolle spielen, zum Beispiel die Kardinalität.

Mehr Unterstützung zur Indexierung findest du in der MongoDB-Dokumentation. Wenn du eine bezahlte Stufe in MongoDB Atlas nutzt, schau dir die integrierten Performance-Advisor-Tools für Index- und Abfrageempfehlungen an.

MongoDB Indexing: Häufige Fragen

Wie viele Indizes sollte ich in einer MongoDB-Collection erstellen?

Es kommt darauf an. Finde ein sinnvolles Gleichgewicht – in der Regel lohnt sich Indexierung für häufig ausgeführte Abfragen, nicht für gelegentliche.

Ich habe mehrere Indizes erstellt, aber meine Abfragen sind weiterhin langsam. Woran liegt das?

Bist du sicher, dass deine Abfragen die erstellten Indizes wirklich nutzen? Verwende den Operator explain oder die Advisor-Tools in MongoDB Atlas zur Fehlersuche.

Muss die Reihenfolge der Indexfelder bei ESR exakt Equality, dann Sort, dann Range sein?

MongoDB kann einen Index in manchen Fällen auch außerhalb der Reihenfolge nutzen. Am wirkungsvollsten ist er jedoch, wenn die Indexreihenfolge der Abfolge in der Abfrage entspricht: zuerst Equality-Filter, dann Sortierung, zuletzt Range.

Welche explain-Modi gibt es?

Standardmäßig läuft explain() im Modus „queryPlanner“. Zusätzlich gibt es die Modi „executionStats“ und „allPlansExecution“.


Nic Raboy's photo
Author
Nic Raboy

Nic Raboy ist Developer Relations Lead bei MongoDB. Er leitet ein Team von Python-, Java-, C#- und PHP-Entwicklern, die großartige Inhalte erstellen, um Entwicklern zu helfen, MongoDB erfolgreich in ihre Projekte einzubinden. Er hat Erfahrung mit Golang und JavaScript und schreibt oft über seine Entwicklungsabenteuer.

Themen
MongoDB

Top-DataCamp-Kurse

Kurs

Einführung in MongoDB mit Python

3 Std.
24.4K
Lerne, wie du flexibel strukturierte Daten mit MongoDB bearbeiten und analysieren kannst.
Details anzeigenKurs Starten

Erstelle dein kostenloses Konto

Üben und Lernpfad deinen Fortschritt.

Weiter Mit Google
Durch Klick auf die Schaltfläche akzeptierst du unsere Nutzungsbedingungen, unsere Datenschutzrichtlinie und die Speicherung deiner Daten in den USA.
Mehr anzeigen
Ähnlich

Tutorial

30 coole Python-Tricks für besseren Code mit Beispielen

Wir haben 30 coole Python-Tricks zusammengestellt, mit denen du deinen Code verbesserst und deine Python-Kompetenzen ausbaust.
Kurtis Pykes 's photo

Kurtis Pykes

15 Min.

Tutorial

Python JSON-Daten: Ein Leitfaden mit Beispielen

Lerne, wie man mit JSON in Python arbeitet, einschließlich Serialisierung, Deserialisierung, Formatierung, Leistungsoptimierung, Umgang mit APIs und Verständnis der Einschränkungen und Alternativen von JSON.
Moez Ali's photo

Moez Ali

6 Min.

Tutorial

Python Datenstrukturen Tutorial

Mach dich mit Python-Datenstrukturen vertraut: Lerne mehr über Datentypen und primitive sowie nicht-primitive Datenstrukturen wie Strings, Listen, Stapel usw.
Sejal Jaiswal's photo

Sejal Jaiswal

24 Min.

Tutorial

Ein Leitfaden zu Python-Hashmaps

Finde heraus, was Hashmaps sind und wie sie in Python mit Hilfe von Wörterbüchern umgesetzt werden.
Javier Canales Luna's photo

Javier Canales Luna

11 Min.

Tutorial

Python-Methode list() mit Beispielen erklärt

Lerne, wie du mit der Python-Funktion index() die Position von Elementen in Listen findest.
Sejal Jaiswal's photo

Sejal Jaiswal

6 Min.

Tutorial

Python-Arrays

Python-Arrays mit Code-Beispielen. Lerne noch heute, wie du mit Python NumPy Arrays erstellen und ausdrucken kannst!
DataCamp Team's photo

DataCamp Team

3 Min.

Mehr anzeigen