Как оптимизировать запрос Djnago ORM?
как можно оптимизировать ORM запрос, получение GDD занимает очень много времени. Я думаю проблема с подзапросом, но через реал "commune__communemeteo" это занимает еще больше времени, (communemeteo около 1 миллиона).
communes = communes.filter(
communeattribute__date__year=year,
communeattribute__date__month=month,
communeattribute__date__day__range=(
days.get("start_date"),
days.get("end_date"),
),
)
gdd_subquery = (
CommuneMeteo.objects.filter(
date__range=(start_date, end_date), commune_id=OuterRef("id")
)
.values("commune_id")
.annotate(gdd=Sum((F("temp_min") + F("temp_max")) / Value(2) - Value(TBASE)))
.values("gdd")[:1]
)
communes = communes.annotate(
plant=Value(f"{plant}", output_field=CharField()),
size=Sum(F("communeattribute__planted_area"), output_field=FloatField()),
gdd=Subquery(gdd_subquery, output_field=FloatField()),
)
```
У меня нет ваших моделей, мне трудно написать код. Вы должны использовать в наборе запросов select_related() для ваших полей FK или prefetch_related() для manytomany
CommuneMeteo.objects.select_related('your_fk_fields',).filter(
date__range=(start_date, end_date), commune_id=OuterRef("id")
)
.values("commune_id")
.annotate(gdd=Sum((F("temp_min") + F("temp_max")) / Value(2) - Value(TBASE)))
.values("gdd")[:1])
Еще одна вещь, которую я могу предложить, - это использовать Pandas и Numpy, если у вас большие данные. Вы потратите некоторое время на изучение, но это будет не зря потраченное время, уверяю вас.
@kirill QuerySet.select_related() и prefetch_related()¶. Используйте их при каждой возможности, ваш код хорошо типизирован, проблема в больших данных, которые у вас есть. ORM queryset имеет ограничения для работы с большими данными. Это работа numpy и Pandas, вот почему они так популярны в python. Мне жаль, что приходится предлагать вам изучить новую библиотеку