2009-07-10 3 views
0

Ich bin ein kleines Programm zu schreiben Fortschritte aufzeichnen Lesen, sind die Datenmodelle einfach:Datastore Zugriffsoptimierung

class BookState(db.Model): 
    isbn = db.StringProperty() 
    title = db.StringProperty(required=True) 
    pages = db.IntegerProperty(required=True) 
    img = db.StringProperty() 

class UpdatePoint(db.Model): 
    book = db.ReferenceProperty(BookState) 
    date = db.DateProperty(required=True) 
    page = db.IntegerProperty(required=True) 

Die UpdatePoint Klasse zeichnet auf, wie viele Seiten der Benutzer auf entsprechende Datum gelesen hat. Nun möchte ich aus den Daten ein Diagramm zeichnen gespeichert in App Engine-Datenbank, sucht die Funktion wie folgt aus:

book = db.get(bookkey) 
ups = book.updatepoint_set 
ups.order('date') 

for (i, up) in enumerate(ups): 
    if i == 0: continue 

    # code begin 
    days = (up.date - ups[i-1].date).days 
    pages = up.page - ups[i-1].page 
    # code end 

    # blah blah 

finde ich, dass für ein Buch mit über 40 Update Punkte, wird es kostet mehr als 4 Sekunden laufen der Code. Und nach dem Timing finde ich, dass das kommentierte Code-Snippet die Ursache für schlechte Performance ist. Jede Schleife kostet ungefähr 0,08 Sekunden oder mehr.

Es scheint, UpdatePoint wird auf eine faule Weise abgerufen, dass es nicht geladen wird, bis es benötigt wird. Ich möchte wissen, ob es eine bessere Lösung gibt, um den Datenzugriff zu beschleunigen, wie die Daten in einem Haufen zu holen.

Vielen Dank für Ihre Antwort.

Antwort

3

Es scheint, dass ich Query-Klasse falsch verwendet. Ich muss zuerst ups.fetch() aufrufen, um die Daten zu bekommen. Jetzt ist der Code viel schneller als zuvor:

book = db.get(bookkey) 
q = book.updatepoint_set 
q.order('date') 
ups = q.fetch(50) 
+0

Ich dachte, das ist, was Ihre updatepoint_set-Funktion tun könnte, als das ist nicht ein Appengine-Aufruf, den ich je gesehen habe. – AutomatedTester

+0

Vielleicht ist updatepoint_set der automatisch generierte Rückverweis, den Sie erhalten, wenn Sie eine Referenz verwenden? http://code.google.com/appengine/docs/python/datastore/entitiesandmodels.html#References –

+1

Verdammt, du hast es herausgefunden, bevor ich antworten konnte. ;) updatepoint_set ist ein Query-Objekt - und die Indizierung führt die Abfrage jedes Mal neu aus. Wenn Sie es einmal abrufen, erhalten Sie wie erwartet ein Array. –

0

Aus dem Blick des Codes, scheint es, dass Ihr langsam nach unten ist, weil seine in der Schleife und müssen irgendwie herausspringen das Objekt finden Sie wollen. Haben Sie versucht, etwas wie

i = 0 
for up in ups: 
    if i != 0: 
    days = (up.date - previous.date).days 
    pages = up.page - previous.page 
    i += 1 
    previous = up 
Verwandte Themen