Django запрос на дублирование дублируется, удваивает время - PullRequest
0 голосов
/ 29 апреля 2019

В моем текущем проекте я хочу выполнить некоторую фильтрацию и упорядочение набора запросов и показать его пользователю в разбивке по страницам.
Это работает нормально, однако меня не устраивает производительность.
Когда яИспользование оператора order_by или явно или неявно с мета-порядком модели позволяет увидеть на панели инструментов отладки, что этот запрос по сути выполняется дважды.
Один раз для счетчика страниц (без ORDER BY) и один раз для извлечения фрагмента объектов.(с ORDER BY).
Из моих наблюдений это приводит к удвоению времени, которое требуется.

Есть ли способ, которым это можно оптимизировать?

Ниже приведен минимальный рабочий пример, в моем реальном приложении я использую представления на основе классов.

class Medium(models.Model):
    title = models.CharField(verbose_name=_('title'),
                             max_length=256,
                             null=False, blank=False,
                             db_index=True,
                             )
    offered_by = models.ForeignKey(Institution,
                                   verbose_name=_('Offered by'),
                                   on_delete=models.CASCADE,
                                   )
    quantity = models.IntegerField(verbose_name=_('Quantity'),
                                   validators=[
                                       MinValueValidator(0)
                                   ],
                                   null=False, blank=False,
                                   )
    deleted = models.BooleanField(verbose_name=_('Deleted'),
                                  default=False,
                                  )

def index3(request):
    media = Medium.objects.filter(deleted=False, quantity__gte=0)
    media = media.exclude(offered_by_id=request.user.institution_id)
    media = media.filter(title__icontains="funktion")
    media = media.order_by('title')
    paginator = Paginator(media, 25)
    media = paginator.page(1)
    return render(request, 'media/empty2.html', {'media': media})

Отладка панели инструментов sql timings

1 Ответ

0 голосов
/ 29 апреля 2019

Запрос точно не дублируется: один является запросом COUNT, другой выбирает фактические объекты для конкретной запрошенной страницы. Это неизбежно, так как Paginator Джанго должен знать общее количество объектов. Однако, если набор запросов media не слишком велик, вы можете оптимизировать его, принудительно оценивая набор запросов media (просто добавьте строку len(media) перед определением Paginator).

Но учтите, что если media очень велико, вам может не потребоваться принудительная оценка media при загрузке всех объектов в память.

...