【发布时间】:2019-05-30 05:55:07
【问题描述】:
我正在尝试提高我的一个 Django 应用程序的性能,以使它们运行得更流畅一些,作为改进我当前运行的第一次迭代的一部分。在进行一些分析时,我注意到我在几个页面上执行了大量的 SQL 查询。
例如,仪表板页面很容易执行 250 多个 SQL 查询。进一步调查指出我的views.py 中的以下代码:
for project in projects:
for historicaldata in project.historical_data_for_n_months_ago(i):
for key in ('hours', 'expenses'):
history_data[key] = history_data[key] + getattr(historicaldata, key)
models.py文件中的相关函数:
def historical_data_for_n_months_ago(self, n=1):
n_year, n_month = n_months_ago(n)
try:
return self.historicaldata_set.filter(year=n_year, month=n_month)
except HistoricalData.DoesNotExist:
return []
如您所见,这将导致对列表中的每个项目执行大量查询。最初是这样设置的,以便将功能集中在模型级别,并在整个应用程序中引入便利功能。
在加载此页面时如何减少正在执行的查询数量有哪些可能的方法?我正在考虑要么删除 convince 函数,而只在视图中使用 select_related(),但是,它仍然需要大量查询才能过滤掉给定年份和月份的记录。
提前非常感谢!
编辑根据要求,提供有关相关模型的更多信息。
项目
class Project(models.Model):
name = models.CharField(max_length=200)
status = models.IntegerField(choices=PROJECT_STATUS_CHOICES, default=1)
last_updated = models.DateTimeField(default=datetime.datetime.now)
total_hours = models.DecimalField(default=0, max_digits=10, decimal_places=2)
total_expenses = models.DecimalField(default=0, max_digits=10, decimal_places=2)
def __str__(self):
return "{i.name}".format(i=self)
def historical_data_for_n_months_ago(self, n=1):
n_year, n_month = n_months_ago(n)
try:
return self.historicaldata_set.filter(year=n_year, month=n_month)
except HistoricalData.DoesNotExist:
return []
历史数据
class HistoricalData(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
year = models.IntegerField()
month = models.IntegerField()
hours = models.DecimalField(max_digits=10, decimal_places=2, default=0)
expenses = models.DecimalField(max_digits=10, decimal_places=2, default=0)
def __str__(self):
return "Historical data {i.month}/{i.year} for {i.person} ({i.project})".format(i=self)
【问题讨论】:
-
可以在这里添加相关模型吗?
-
信息已添加!