我有看法。它从模型中获取大约1000条记录并计算每两个值。它工作正常,但大约1分钟很慢。
我的模特。它包含每天的读数:
class Reading(models.Model):
meter = models.ForeignKey(Meter, verbose_name=_('meter'))
reading = models.FloatField(verbose_name=_('reading'))
code = models.ForeignKey(ReadingCode, verbose_name=_('code'))
date = models.DateTimeField(verbose_name=_('date'))
class Meta:
get_latest_by = 'date'
ordering = ['-date', ]
def __unicode__(self):
return u'%s' % (self.date,)
@property
def consumption(self):
try:
end = self.get_next_by_date(code=self.code, meter=self.meter)
return (end.reading - self.reading) / (end.date - self.date).days
except:
return 0.0
@property
def middle_consumption(self):
data = []
current_year = self.date.year
for year in range(current_year - 3, current_year):
date = datetime.date(year, self.date.month, self.date.day)
try:
data.append(Reading.objects.get(
date = date,
meter = self.meter,
code = self.code
).consumption)
except:
data.append(0.0)
for i in data:
if not i:
data.pop(0)
return sum(data) / len(data)
我的观点。它会返回json,其中包含所请求的流量计的所有读数以及过去3年的计算消耗量和计算的中间消耗量。
class DataForDayChart(TemplateView):
def get(self, request, *args, **kwargs):
output = []
meter = Meter.objects.get(slug=kwargs['slug'])
# TODO: Make it faster
for reading in meter.readings_for_period().order_by('date'):
output.append({
"label": reading.date.strftime("%d.%m.%Y"),
"reading": reading.reading,
"value": reading.consumption / 1000,
"middle": reading.middle_consumption / 1000
})
return HttpResponse(output, mimetype='application/json')
我应该更改什么才能让它更快?
答案 0 :(得分:2)
性能问题可能是由过多的数据库操作引起的,例如:在方法middle_consumption中,您至少查询db两次,
end = self.get_next_by_date(code=self.code, meter=self.meter)
...
data.append(Reading.objects.get(
date = date,
meter = self.meter,
code = self.code
).consumption)
你没有显示所有代码,所以我想以下循环中的每一步都需要sql查询。
for reading in meter.readings_for_period().order_by('date'):
正如你所说,只有1000条记录,也许你可以加载一次数据并操纵内存中的关系和计算,这样可以提高整体性能。
答案 1 :(得分:0)
从视图名称来看,我认为它的数据在白天变化不大;在这种情况下,我建议你使用缓存 Django有一个很好的caching framework,设置和使用非常简单直接,它会立即产生巨大的变化,而不需要太多努力。
当然,第一次通话仍然会很慢;在那里,你可能想要优化它
优化中的常用方法首先是测量,您应该对视图进行分析,以查看最慢的功能。
或者,您也可以插入一些print语句来获取减速发生位置的要点;这里的优点是,您不需要学习如何使用新工具。
那就是说,我最好的猜测是在meter.readings_for_period()
(你的代码没有发布)的调用中发生了减速,并且是由于一些低效的数据库查询 - 例如,最终指示ORM检索记录一个接一个,而不是一个select语句。