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

MongoDB-Aggregatpipeline langsam nach dem ersten Match-Schritt

ANTWORT 2019

Diese Antwort gilt für MongoDB 4.2

Nachdem ich die Frage und die Diskussion zwischen Ihnen gelesen habe, glaube ich, dass das Problem gelöst ist, aber die Optimierung immer noch ein häufiges Problem für alle ist, die MongoDB verwenden.

Ich hatte das gleiche Problem, und hier sind die Tipps zur Abfrageoptimierung.

Korrigiert mich, wenn ich falsch liege :)

1. Index zur Sammlung hinzufügen

Indizes spielen eine wichtige Rolle bei der schnellen Ausführung von Abfragen, da Indizes Datenstrukturen sind, die den Datensatz der Sammlung in einer Form speichern können, die leicht zu durchlaufen ist. Abfragen werden effizient mit Hilfe von Indizes in MongoDB ausgeführt.

Sie können je nach Bedarf einen anderen Indextyp erstellen. Erfahren Sie hier mehr über Indizes, die offizielle MongoDB-Dokumentation.

2. Pipeline-Optimierung

  • Immer $match vor $project verwenden , da Filter zusätzliche Dokumente und Felder aus der nächsten Stufe entfernen.
  • Denken Sie immer daran, Indizes werden von $match und $sort verwendet . Versuchen Sie also, den Feldern, nach denen Sie Dokumente sortieren oder filtern, einen Index hinzuzufügen.
  • Versuchen Sie, diese Reihenfolge in Ihrer Abfrage beizubehalten, verwenden Sie $sort vor $limit wie $sort + $limit + $skip. Weil $sort den Index nutzt und es MongoDB ermöglicht, den erforderlichen Abfrageplan auszuwählen, während die Abfrage ausgeführt wird.
  • Verwenden Sie immer $limit vor $skip sodass Überspringen angewendet wird, um Dokumente einzuschränken.
  • Verwenden Sie $project um im nächsten Schritt nur die notwendigen Daten zurückzugeben.
  • Erstellen Sie immer einen Index für die ForeignField-Attribute in einem $lookup . Da die Suche ein Array erzeugt, wickeln wir es im Allgemeinen in der nächsten Phase ab. Also, anstatt es in der nächsten Stufe abzuwickeln, wickeln Sie es in der Suche ab wie:

    {
    $lookup: {
        from: "Collection",
        as: "resultingArrays",
        localField: "x",
        foreignField: "y",
        unwinding: { preserveNullAndEmptyArrays: false }
    

    }}

  • Verwenden Sie allowDiskUse in der Aggregation, mit deren Hilfe Aggregationsoperationen Daten in das Unterverzeichnis _tmp im Datenbankpfadverzeichnis schreiben können. Es wird verwendet, um die große Abfrage im temporären Verzeichnis durchzuführen. Zum Beispiel:

     db.orders.aggregate(
     [
            { $match: { status: "A" } },
            { $group: { _id: "$uid", total: { $sum: 1 } } },
            { $sort: { total: -1 } }
     ],
     {
            allowDiskUse: true
     },
     )
    

3. Erstellen Sie die Indizes neu

Wenn Sie häufig Indizes erstellen und löschen, erstellen Sie Ihre Indizes neu. Es hilft MongoDB, den zuvor gespeicherten Abfrageplan im Cache zu aktualisieren, der weiterhin den erforderlichen Abfrageplan übernimmt, glauben Sie mir, dieses Problem ist scheiße :(

4. Unerwünschte Indizes entfernen

Zu viele Indizes nehmen beim Erstellen, Aktualisieren und Löschen zu viel Zeit in Anspruch, da sie neben ihren Aufgaben auch einen Index erstellen müssen. Es hilft also sehr, sie zu entfernen.

5. Dokumente einschränken

In einem realen Szenario hilft das Abrufen vollständiger in der Datenbank vorhandener Daten nicht. Außerdem können Sie es entweder nicht anzeigen oder der Benutzer kann die abgerufenen Daten nicht vollständig lesen. Anstatt also vollständige Daten abzurufen, holen Sie Daten in Blöcken ab, was sowohl Ihnen als auch Ihrem Client hilft, diese Daten zu beobachten.

Und schließlich hilft es, zu beobachten, welcher Ausführungsplan von MongoDB ausgewählt wird, um das Hauptproblem herauszufinden. $explain wird Ihnen also dabei helfen, das herauszufinden.

Ich hoffe, diese Zusammenfassung wird euch helfen, könnt ihr gerne neue Punkte vorschlagen, wenn ich welche übersehen habe. Ich werde sie auch hinzufügen.