thejaz
thejaz

Reputation: 2773

How to model my app in the Google App Engine Datastore

I have a hard time to model my applications data to get reasonable performance.

It is an application that track costs within a group of people and today I have the following entities:

class Event(db.Model):
    # Values
    name = db.StringProperty(required=True)
    password = db.StringProperty(required=True)

class Person(db.Model):
    # References
    event = db.ReferenceProperty(Event, required=True)
    # Values
    name = db.StringProperty(required=True)

class Transaction(db.Model):
    # References
    event = db.ReferenceProperty(Event, required=True)
    paidby = db.ReferenceProperty(Person, required=True)
    # Values
    description = db.StringProperty(required=True)
    amount = db.FloatProperty(required=True)
    datetime = db.DateTimeProperty(auto_now_add=True)

# This is used because a transaction might not distribute costs
# evenly across all persons belonging to the event
class TransactionPerson(db.Model):
    # References
    event = db.ReferenceProperty(Event, required=False)
    transaction = db.ReferenceProperty(Transaction, required=True)
    person = db.ReferenceProperty(Person, required=True)
    # Values
    amount = db.FloatProperty(required=True)

The problem is when I for example want to calculate the balance for each person, then I have to get all the data associated with an event and loop through all TransactionPerson for each Transaction/Person combination (in the below example that is ~65.000 operations)

I have an event example with:

And a request to the start page that shows this balance summary per person and all transactions takes:

real: 1863ms
cpu: 6900ms (1769ms real)
api: 2723ms (94ms real)

At the moment I only do 3 RPC requests to get all persons, transactions and transactionpersons for an event and then do all the "relational" work in the application, thats why the cpu ms is pretty high.

Questions:

  1. It takes 2723ms api cpu to only get the 293 objects from 3 datastore requests, isn't that pretty high? The real time is OK (94ms), but it takes a lot from my api cpu quotas?

  2. How can I design this to get a lot better performance? Real ms today is 1863 for this example above, but if there are for example 12 persons the time would triple. These are not acceptable response times.

Thanks!

Upvotes: 0

Views: 191

Answers (1)

Wooble
Wooble

Reputation: 89847

Generally you want to optimize for reads.

Instead of calculating a person's balance at read time, calculate changes at write time and denormalize, storing the calculated balance in the Person entity.

Upvotes: 1

Related Questions