Aus der MongoDB
Dokumentation geht hervor, dass:
Wenn Sie nur eine Teilmenge von Feldern aus Dokumenten benötigen, können Sie eine bessere Leistung erzielen, indem Sie nur die Felder zurückgeben, die Sie benötigen
Wie wirken sich Filterfelder auf die Leistung aus? Hängt die Leistung mit der Größe der Daten zusammen, die über das Netzwerk übertragen werden? oder die Größe der Daten, die im Speicher gespeichert werden? Wie genau wird diese Leistung verbessert? Was ist diese Leistung, die in der Dokumentation erwähnt wurde?
Ich habe langsame MongoDB-Abfragen. Beeinflusst die Rückgabe einer Teilmenge meine langsame Abfrage (ich habe einen zusammengesetzten Index für das Feld)?
mongodb
projection
ALH
quelle
quelle
Debian 8
,MongoDB 3.6.2
Antworten:
Standardmäßig geben Abfragen alle Felder in übereinstimmenden Dokumenten zurück. Wenn Sie alle Felder benötigen, ist die Rückgabe vollständiger Dokumente effizienter, als wenn der Server die Ergebnismenge mit Projektionskriterien bearbeitet.
Die Verwendung der Projektion zur Begrenzung der Felder, die aus Abfrageergebnissen zurückgegeben werden sollen, kann jedoch die Leistung verbessern, indem:
Wenn Sie mithilfe der Projektion nicht verwendete Felder entfernen, muss der MongoDB-Server jedes vollständige Dokument in den Speicher abrufen (sofern es noch nicht vorhanden ist) und die zurückzugebenden Ergebnisse filtern. Diese Verwendung der Projektion verringert nicht die Speichernutzung oder den Arbeitssatz auf dem MongoDB-Server, kann jedoch abhängig von Ihrem Datenmodell und den projizierten Feldern erhebliche Netzwerkbandbreite für Abfrageergebnisse einsparen.
Eine abgedeckte Abfrage ist ein Sonderfall, bei dem alle angeforderten Felder in einem Abfrageergebnis im verwendeten Index enthalten sind, sodass der Server nicht das vollständige Dokument abrufen muss. Abgedeckte Abfragen können die Leistung (durch Vermeiden des Abrufs von Dokumenten) und die Speichernutzung verbessern (wenn für andere Abfragen nicht dasselbe Dokument abgerufen werden muss).
Beispiele
mongo
Stellen Sie sich zu Demonstrationszwecken über die Shell vor, Sie hätten ein Dokument, das so aussieht:Das Feld
b
kann eine Auswahl von Werten darstellen (oder in diesem Fall eine sehr lange Zeichenfolge).Erstellen Sie als Nächstes einen Index für
{a:1}
ein häufig verwendetes Feld, das von Ihrem Anwendungsfall abgefragt wird:Ein einfaches
findOne()
ohne Projektionskriterium gibt ein Abfrageergebnis zurück, das ungefähr 10 MB beträgt:Durch Hinzufügen der Projektion
{a:1}
wird die Ausgabe auf das Felda
und das Dokument beschränkt_id
(das standardmäßig enthalten ist). Der MongoDB-Server bearbeitet noch ein 10-MB-Dokument, um zwei Felder auszuwählen, aber das Abfrageergebnis beträgt jetzt nur noch 33 Byte:Diese Abfrage wird nicht behandelt, da das vollständige Dokument abgerufen werden muss, um den
_id
Wert zu ermitteln. Das_id
Feld ist standardmäßig in den Abfrageergebnissen enthalten, da es die eindeutige Kennung für ein Dokument ist, jedoch_id
nicht in einen Sekundärindex aufgenommen wird, sofern es nicht ausdrücklich hinzugefügt wird.Die
totalDocsExamined
undtotalKeysExamined
Metriken in denexplain()
Ergebnissen zeigen, wie viele Dokumente und Indexschlüssel untersucht wurden:Diese Abfrage kann mithilfe der Projektion verbessert werden, um das
_id
Feld auszuschließen und eine abgedeckte Abfrage nur mit dem{a:1}
Index zu erstellen . Die abgedeckte Abfrage muss kein ~ 10 MB großes Dokument mehr in den Speicher abrufen und ist daher sowohl bei der Netzwerk- als auch bei der Speichernutzung effizient:Dies ist ohne den Kontext einer bestimmten Abfrage, eines Beispieldokuments und der vollständigen EXPLAIN-Ausgabe nicht zu beantworten. Sie können jedoch einige Benchmarks in Ihrer eigenen Umgebung für dieselbe Abfrage mit und ohne Projektion ausführen, um das Ergebnis zu vergleichen. Wenn Ihre Projektion die Gesamtausführungszeit für Abfragen (Verarbeitung und Übertragung von Ergebnissen) erheblich verkürzt, kann dies ein starker Hinweis darauf sein, dass Ihr Datenmodell verbessert werden könnte.
Wenn nicht klar ist, warum eine Abfrage langsam ist, ist es am besten, eine neue Frage mit bestimmten Details zu veröffentlichen, um sie zu untersuchen.
quelle
Mit einer Projektion können Sie eine Situation erreichen, in der die Ergebnismenge direkt aus dem Index stammt.
Wenn Sie einen zusammengesetzten Index haben,
{x:1, y:1, z:1}
bei dem keines von x, y, z _id ist, müssen Sie projizieren,{_id:0, x:1, y:1, z:1}
da er_id
immer als Teil der Ergebnismenge zurückgegeben wird (wenn er nicht wegprojiziert wird) und die Engine Datendateien lesen muss, um ihn abzurufen. Dies liegt daran, dass der Index nicht den Wert _id hat, sondern nur auf das Dokument verweist, in dem der Wert gespeichert ist.quelle
_id
aus der zurückgegebenen Antwort entferne , passt das in den Arbeitsspeicher? Hilft das?_id:0
wird das Ergebnis vollständig aus dem RAM zurückgegeben, ohne Daten von der Festplatte zu lesen.