6

I'm using django/apache/sqlite3 and I have a django model that looks like this:

class Temp_entry(models.Model):
    dateTime = models.IntegerField() #datetime
    sensor = models.IntegerField()   # id of sensor
    temp = models.IntegerField()     # temp as temp in Kelvin * 100

I'm trying to get the last 300 Temp_entry items to place into a graph. I do that this way:

revOutsideTempHistory = Temp_entry.objects.filter(sensor=49).order_by('dateTime').reverse()[:300]

However, this query takes ~1 second. Is there a way to improve this? I've dug around and found that order_by is horrible inefficient, so I'm hoping that there is a viable alternative?

An alternative I thought of, but can't figure out how to implement, would be to run the query every 20 minutes and keep it cached, that would be acceptable too, as the data can be slightly stale with no ill effects.

4 Answers 4

7

If caching is acceptable it always should be used. Something like:

from django.core.cache import cache

cached = cache.get('temp_entries')
if cached:
    result = cached 
else:
    result = Temp_entry.objects.filter(sensor=49).order_by('dateTime').reverse().values_list()[:300]
    cache.set('temp_entries', result, 60*20)  # 20 min

Also you can set db_indexes for the appropriate columns

class Temp_entry(models.Model):
    dateTime = models.IntegerField(db_index=True) #datetime
    sensor = models.IntegerField(db_index=True)   # id of sensor
    temp = models.IntegerField()     # temp as temp in Kelvin * 100
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Alexey, two followup questions: is there a way to have the query run every 20 minutes instead of waiting for the request to check if it's stale? What does the db_indexes do?
Andy, db_index just creates normal database index, which will increase a query speed. However, this speedup is nothing compared to caching. Also note that such DBs like Mysql and Postgre has internal caching of queries, but not sure about sqlite. According to the first question: yes you can using django command and something like cron or celery but I think this is not good solution
Thanks Alexey, using the indexes and caching the view is rendering in an acceptable amount of time
3

Johnny Cache! http://packages.python.org/johnny-cache/ It works out-of-the-box, and it works well!

1 Comment

Good solution, though how good it is depend on your R/W patterns!
2

You probably need to add some more indexes in your database. Use the django-debug toolbar to get the SQL of the actual query that's being run, and use the EXPLAIN feature to show what indexes it's using. For this particular query, I'd imagine you need to add an index on (sensor, dateTime) - do that directly in the database shell.

1 Comment

in another comment on this thread the OP asked a question about what an index does. I thought I'd point that out for you.
0

Well, if you know your entries always have an increasing dateTime (i.e. the dateTime is set when the entry is created and not edited), then you don't have to order by dateTime as they will naturally be in that order in the database.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.