In einer Python GAE-Anwendung, an der ich arbeite, müssen wir n Zeilen aus dem Speicher abrufen, und wir stoßen auf Leistungsprobleme für n> 100. Wir erwarten, dass n in den meisten Fällen weniger als 10000 ist.Wie schnell eine Anzahl von Zeilen aus dem Datenspeicher abrufen?
Also lassen Sie uns ein einfaches Modell betrachten:
class MyEntity(ndb.Model):
field1 = nbd.StringProperty()
field2 = ndb.StringProperty()
#...
fieldm = ndb.StringProperty()
# m is quite large, maybe ~ 30. Stored strings are short - in the order of 30 characters or less
Ich habe den Datenspeicher mit einigen Daten gefüllt, und bekam wirklich schlechte Leistung Ebene fetch()
verwenden. Ich habe seither alle Filter entfernt und nur versucht, eine Anzahl von Entitäten zu bekommen, scheint sehr schlechte Leistung zu bekommen (im Vergleich zu dem, was ich zum Beispiel für jede gebräuchliche SQL-Implementierung erwarte. Ich weiß, dass wir GAE nicht vergleichen sollten SQL, aber nur flache Zeilen runter - ich würde erwarten, mehr Leistung zu sein, nicht weniger). Hier ist, was ich versucht habe:
- Der einfachste Ansatz
MyEntity.all().fetch(n)
. Dies skaliert linear mitn
, was erwartet wird. Obwohl ich nicht erwartet habe, dass es 7s fürn = 1000
dauert. - Der Versuch,
fetch()
mit jedem vernünftigenbatch_size
zu zwingen, verschlechtert die Leistung weiter. Ich habe versucht Werte von 1 bis 1000. - Doing gibt eine Größenordnung Verbesserung.
- Eine Abfrage manuell durchführen (
through ndb.Query
), und nur ein einzelnes Feld herausgeben gibt eine kleine Verbesserung in der Größenordnung von 1,2. - Doing a
fetch_async(n)
und warten gibt genau die gleiche Leistung. - Teilen Sie den Job in Teile, dann tun
fetch_async(n/p, offset=...)
und dann warten und Beitritt alle Futures - gibt bestenfalls die gleiche Leistung, im schlimmsten Fall - viel schlechtere Leistung. - ähnliche Geschichte mit
fetch_page()
hat ich versucht, auch db
statt ndb
verwenden, und die Ergebnisse sind so ziemlich das gleiche. Also, jetzt bin ich mir nicht sicher, was ich tun soll? Gibt es eine Möglichkeit, eine halbwegs ordentliche Leistung für n
in der Größenordnung von 10000 zu bekommen? Selbst wenn ich meine Entitäten zu einzelnen Feldern vereinfache, ist die Leistung zu schlecht. Ich erwarte, dass die gesamte unkomprimierte Nutzlast ungefähr 1 MB beträgt. Das Herunterladen von 1 MB innerhalb einer Minute ist eindeutig inakzeptabel.
Ich sehe dieses Problem live, aber für Leistungstests verwende ich Remote-API. Meine Frage ähnelt dieser Frage zu SO: Best practice to query large number of ndb entities from datastore. Sie schienen keine Lösung zu finden, aber sie wurde vor 4 Jahren gefragt, vielleicht gibt es jetzt eine.
Was sehen Sie in den Protokollen für diese Anfrage? –
Was möchten Sie tun, nachdem Sie die Zeilen abgerufen haben? – Vincent