Die gepufferte Datennutzung der Überlaufsortierungsstufe überschreitet den internen Grenzwert

85

Verwenden des Codes:

all_reviews = db_handle.find().sort('reviewDate', pymongo.ASCENDING)
print all_reviews.count()

print all_reviews[0]
print all_reviews[2000000]

Die Zählung wird gedruckt 2043484und es wird gedruckt all_reviews[0].

Beim Drucken all_reviews[2000000]wird jedoch folgende Fehlermeldung angezeigt:

pymongo.errors.OperationFailure: Datenbankfehler: Runner-Fehler: Die gepufferte Datennutzung der Überlaufsortierungsstufe von 33554495 Byte überschreitet das interne Limit von 33554432 Byte

Wie gehe ich damit um?

sheetal_158
quelle

Antworten:

118

Bei einer In-Memory-Sortierung stoßen Sie auf die 32-MB-Grenze:

https://docs.mongodb.com/manual/reference/limits/#Sort-Operations

Fügen Sie dem Sortierfeld einen Index hinzu. Auf diese Weise kann MongoDB Dokumente in sortierter Reihenfolge an Sie streamen, anstatt zu versuchen, sie alle in den Speicher des Servers zu laden und im Speicher zu sortieren, bevor sie an den Client gesendet werden.

A. Jesse Jiryu Davis
quelle
7
Es ist besser, einen Index zu deklarieren, damit Sie nicht im RAM sortieren müssen: schneller und zuverlässiger, begrenzte RAM-Nutzung statt potenziell unbegrenzt. Wenn Sie darauf bestehen, verwandeln Sie Ihren "Fund" in eine Aggregation (die 100 MB RAM zum Sortieren verwenden kann) und setzen Sie allowDiskUse: true, um das Aggregationsframework anzuweisen, auf die Festplatte zu übertragen, wenn es 100 MB RAM überschreiten würde. Erwarten Sie eine schwerwiegende Leistungseinbuße im Vergleich zur Angabe eines geeigneten Index. docs.mongodb.org/manual/reference/operator/aggregation/sort/…
A. Jesse Jiryu Davis
31
Eigentlich kann es geändert werden. Sie müssen diesen Befehl ausführen : db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes: <limit in bytes>}). Quelle: askubuntu.com/questions/501937/…
kumarharsh
6
Für Mungo-Benutzer ist es gut zu beachten, dass das Setzen von index: true auf der Requisite in Ihrem Schema dieses Problem behebt. Mungo durchläuft alle Ihre Schemas und stellt sicher, dass die Felder tatsächlich Indizes sind, bevor Sie die App starten Sie deaktivieren dieses Verhalten mit mySchema.set ('autoIndex', false).
Benjamin Conant
2
Ich habe einen Index für das Sortierfeld erstellt, aber es gibt mir immer noch den Fehler "Sortieroperation verwendet mehr als die maximalen 33554432 Bytes RAM". Dies kann daran liegen, dass ich vor der Sortierung eine Übereinstimmungsoperation anwende und laut Mongo Doc, wenn Sie Übereinstimmung vor der Sortierung verwenden Bei dieser Operation wird der Index vernachlässigt und die Speichersortierung für alle übereinstimmenden Datensätze durchgeführt.
Amol Suryawanshi
11
Wenn dies die akzeptierte Antwort ist, sollte sie Informationen zum Hinzufügen eines Index enthalten.
Philipp Ludwig
45

Wie kumar_harshim Kommentarbereich erwähnt, möchte ich noch einen weiteren Punkt hinzufügen.

Sie können die aktuelle Puffernutzung mit dem folgenden Befehl über die adminDatenbank anzeigen :

> use admin
switched to db admin
> db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )
{ "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 }

Der Standardwert beträgt 32 MB (33554432 Byte). In diesem Fall gehen Ihnen die Pufferdaten aus, sodass Sie das Pufferlimit mit Ihrem eigenen definierten optimalen Wert erhöhen können, z. B. 50 MB wie folgt:

>  db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432})
{ "was" : 33554432, "ok" : 1 }

Wir können dieses Limit auch dauerhaft über den folgenden Parameter in der Mongodb-Konfigurationsdatei festlegen:

setParameter=internalQueryExecMaxBlockingSortBytes=309715200

Hoffe das hilft !!!

Note: Dieser Befehl wird erst nach Version 3.0 + unterstützt

JERRY
quelle
Wie kann dieses Limit dauerhaft in der Konfigurationsdatei festgelegt werden? Ich habe eine 1-TB-Speichermaschine für Mongo und möchte sie dauerhaft aufdrehen.
Samantha Atkins
@SamanthaAtkins Ich habe die Antwort aktualisiert, um dies dauerhaft in der Konfigurationsdatei festzulegen.
JERRY
@JERRY wo dauerhaft in Schienen setzen. Schienen 5 / mongoid.yml?
Prateep Kul
Ich habe es gefunden. Laufen Sie an meinem Terminal mit: mongod und folgen Sie dem Handbuch zocada.com/setting-mongodb-users-beginners-guide
Prateep Kul
24

mit Indizierung gelöst

db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])
sheetal_158
quelle
Stellen Sie sicher, dass Sie keinen spärlichen Index verwenden. Sie werden ignoriert, wenn Sie nach jedem Dokument sortieren
Charly Koza,
14

Wenn Sie vermeiden möchten, einen Index zu erstellen (z. B. nur eine schnelle und schmutzige Überprüfung, um die Daten zu untersuchen), können Sie die Aggregation mit Datenträgernutzung verwenden:

all_reviews = db_handle.aggregate([{$sort: {'reviewDate': 1}}], {allowDiskUse: true})

(Ich bin mir jedoch nicht sicher, wie ich das in Pymongo machen soll).

poroszd
quelle
In Pymongo wäre db_handle.aggregate(pipe, allowDiskUse=True). Siehe diese Frage für weitere Informationen!
Genarito
3

JavaScript-API-Syntax für den Index:

db_handle.ensureIndex({executedDate: 1})
wytten
quelle
2

In meinem Fall war es notwendig, notwendige Indizes im Code zu korrigieren und neu zu erstellen:

rake db:mongoid:create_indexes RAILS_ENV=production

Da der Speicherüberlauf nicht auftritt, wenn ein erforderlicher Feldindex vorhanden ist.

PS Vorher musste ich die Fehler beim Erstellen langer Indizes deaktivieren:

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )

Kann auch benötigt werden reIndex:

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> use your_db
switched to db your_db
> db.getCollectionNames().forEach( function(collection){ db[collection].reIndex() } )
shilovk
quelle