提升Django数据库查询性能

6 投票
4 回答
4604 浏览
提问于 2025-04-17 09:08

我正在使用django、apache和sqlite3,并且我有一个django模型,长得像这样:

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

我想获取最后300个Temp_entry项目,以便放到一个图表中。我是这样做的:

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

不过,这个查询大约需要1秒钟。有没有什么办法可以让它更快一些?我查了一下,发现order_by这个方法效率很低,所以我希望能找到一个更好的替代方案。

我想到的一个替代方案是每20分钟运行一次查询,然后把结果缓存起来,这样也可以,因为数据稍微过时一点也没关系。

4 个回答

2

你可能需要在你的数据库里添加一些索引。可以使用django-debug工具栏来查看实际执行的SQL查询,并利用EXPLAIN功能来查看它使用了哪些索引。对于这个特定的查询,我想你需要在(sensor, dateTime)上添加一个索引——可以直接在数据库的命令行中进行操作。

3

Johnny Cache!http://packages.python.org/johnny-cache/ 这个工具开箱即用,而且效果很好!

7

如果可以使用缓存,那就应该尽量使用它。比如说:

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

你还可以为合适的列设置数据库索引

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

撰写回答