How to model my app in the Google App Engine Datastore
I have a hard time to model my applications data to get reasonable performa开发者_StackOverflow社区nce.
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:
- 4 Persons
- 76 Transaction
- 213 TransactionPerson
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:
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?
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!
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.
精彩评论