Как оптимизировать эти запросы Django для более быстрого выполнения?
У меня есть список моделей campaign_list
, как показано ниже, в каждой модели есть некоторые общие поля (например, overall_score, audit_date, audit_id). Я хочу найти средний балл для каждого месяца. Я написал код ниже, и он работает, но время выполнения больше. Я хочу оптимизировать время выполнения. Время выполнения увеличивается по мере увеличения количества записей (в настоящее время у меня 200k+ записей и добавление).
# List of 40 Models
campaign_list = [Model1, Model2, Model3, ....., ModelN]
# Method 1
campaign_score = sum([sum([j.overall_score for j in i.objects.filter(audit_date__range=[start_date, todays_date])]) for i in campaign_list])
# Method 2
campaign_score = 0
for i in campaign_list:
score = sum([j.overall_score for j in i.objects.filter(audit_date__range=[start_date, todays_date])])
campaign_score += score
Если у вас действительно есть список классов моделей, нетривиально сделать все в одном запросе, но, по крайней мере, вы можете использовать Sum
агрегат для суммирования по каждой модели в базе данных.
# List of 40 Models
campaign_list = [Model1, Model2, Model3, ...]
campaign_score = 0
for campaign_model in campaign_list:
res = campaign_model.objects.filter(
audit_date__range=[start_date, todays_date]
).aggregate(score=Sum("overall_score"))
if res.get("score"):
campaign_score += res["score"]
Я предполагаю, что у вас есть различные модели с внешним ключом модели Audit и, таким образом, есть общее поле audit_id. Поэтому мы можем объединить модели с помощью метода ORM select_related. После объединения столбцы будут разными для каждой модели, как специально overall_score. Мы можем агрегировать значение, используя F каждого столбца и получим общий балл.
Audit.objects.select_related('model2', 'model3', 'model4')
.aggregate(
score=F('overall_score') + F('model2__overall_score') + F('model3__overall_score') + F('model4__overall_score').get('score')
)
При использовании этого запроса выполняется только один запрос. Вы можете проверить с помощью
from django.db import connection, reset_queries
reset_queries()
Audit.objects.select_related('model2', 'model3', 'model4')
.aggregate(
score=F('overall_score') + F('model2__overall_score') + F('model3__overall_score') + F('model4__overall_score').get('score')
)
print(connection.queries)
reset_queries()
Как сказал @AKX, если у вас огромные данные, то вам следует использовать индекс и сэкономить время.