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?

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.


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


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)])

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).


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})

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() } )
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.