Оптимизация запроса в цикле FOR
Как оптимизировать следующий запрос, чтобы устранить цикл? Количество кодов составляет несколько сотен, поэтому я получаю несколько сотен запросов к базе данных, что неприемлемо.
n = 3
result = []
codes = Target.objects.filter(code__in=['ABC', 'CDE', ...])
for code in codes:
result.append(Data.objects.select_related('target')
.filter(target__code=code)
.values('spec', 'spec_type')
.order_by('-spec')[:n])
Модели:
class Data(models.Model):
target = models.ForeignKey(Target)
spec_type = models.CharField()
spec = models.FloatField()
class Target(models.Model):
code = models.TextField(db_index=True)
Не обязательно получать codes
в виде QuerySet
для перечисления. Мы можем напрямую работать со списком кодов.
Если вы хотите построить QuerySet
, содержащий все заданные элементы, вы можете сделать QuerySet
с union, который будет извлекать эти объекты. В таком случае это можно сделать с помощью .union(…)
[Django-doc]:
codes = ['ABC', 'CDE']
n = 3
result = Data.objects.none().union(
*[
Data.objects.filter(target__code=code).values('spec', 'spec_type').order_by('-spec')[:n]
for code in codes
],
all=True
)
Как сказал @Willem Van Onsem, вам не нужно получать queryset ваших объектов Target
, поскольку у вас уже есть нужные вам коды. Просто храните коды в переменной, а затем вы можете сделать django запрос, используя этот список.
codes = ['ABC', 'CDE', ...]
result = Data.objects.filter(target__code__in = codes)
Этот запрос должен вернуть все Data
объекты, код связанного Target
объекта которых находится в списке codes
.