views:

99

answers:

2

I am searching the Final model (defined below) with a query which filters on its name property. This query is taking about 2200ms to execute on the development server. How can I speed it up? Here is an AppStats screenshot.

I was filtering on the created field too, but this was taking in excess of 10000ms so I've removed that part of the query for now.

class Final(db.Model):
    name = db.StringProperty()     # 7 characters long
    author = db.StringProperty()
    rating = db.FloatProperty()
    created = db.DateTimeProperty()

# this is the important part of the request (AppStats shows that these two
# queries take about 2200ms each).

 query = Final.all()
 query2 = Final.all()
 query.filter('name = ', link1)
 query2.filter('name = ', link2)
 aa = query.fetch(10000)
 bb = query2.fetch(10000)
A: 

A few ways you might be able to speed up this query:

  1. Use the SQLite backend for the development server (it might be faster).

  2. Can you store integer IDs instead of string IDs for name? This might make the entities smaller and thus take less time to transfer and deserialize them. It is also easier to check integer equality than string equality so the filter operation might be faster for the datastore to perform.

  3. If name is large, you could potentially save some time by moving the author name and rating into a separate child model. Then you could use an ancestor query to fetch the relevant child models - thus you will save transfer and deserialization time by only only fetching the fields you need.

David Underhill
hmmm my names are unique identifier strings of the form /s/s_/s/s/s/s I don't think I would see that much improvement with integers. My other thought is to when I populate table Final, for a given name, create anther table with the name and a dictionary of the instances that include that name, then I can call that name in the table, get the keys and place that call to the Final table. That would suggest though that the filter is my biggest time delay?
Is `s` a single character?
David Underhill
woops yes /s string char, eg. t3_cpv6h
So the `name` field is pretty small then. Have you tried using the sqlite backend yet?
David Underhill
hmmmm no I just started looking at the page,
yes its taking about 2 seconds for 30 instances with the same name, and about 2 seconds for a 200 instance with the same name for each.
Hey you would suggest using the sqlite backend instead of what I am thinking of which is, as I populate the table Final, populate another table with the name, and the key_names of all the instances in Final that have that name, and merely call that name in the table get the keys and make a call to Final table? I am thinking might be faster than filter command?
where do you put this it doesn't say? --use_sqlite=true
That is a command-line argument to the development server program: `dev_appserver.py --use_sqlite=true ...`
David Underhill
yep I understand that, I could use that but is there a way to set the flag for the sdk console?
+1  A: 

While David's suggestions are good ones, optimizing for speed on the development server is probably a bad idea. The development server's performance does not reflect that of the production server, and optimizations based on development server runtime may not fare well in production.

In general, you can assume that the performance of the development server will decrease as records are added, whilst this is definitely not the case in production, where your query runtime depends only on the size of the result set. If you can reduce the size of your sample dataset in production, that may be your best option for speeding development up.

Nick Johnson
Hi, thx for the advice from both you guys, I havn't tried implementing the code on the production server yet I guess that is my problem :), I will try that and see if the code runs fast.