Повышение производительности набора запросов - PullRequest
0 голосов
/ 05 марта 2019

Я изучаю DRF и экспериментирую с набором запросов.Я пытаюсь оптимизировать работу максимально эффективно. Цель состоит в том, чтобы получить список оценок для активных студентов, специализирующихся в области «Искусство».

На основе методов оптимизации базы данных , я провел несколько разныхобновления и не вижу разницы, когда я смотрю на время, возвращаемое через вкладку сети консоли.Однако я ДЕЛАЮ, что вижу меньше журналов в сканировании Seq, когда запускаю метод .explain () при фильтрации моделей. Выполняю ли я что-нибудь этим?

Например: Grades.objects.filter (student_id__in = list (student_list)). Order_by ()

Что-нибудьеще я могу сделать, чтобы улучшить приведенный ниже код, который я мог бы пропустить?- За исключением добавления каких-либо изменений модели внешнего или первичного ключа.

class GradeViewSet(viewsets.ModelViewSet):
    serializer_class = GradesSerializer

    def retrieve(self, request, *args, **kwargs):
        active_students = Student.objects.filter(active=True)
        student_list = active_students.filter(major='Art').values_list('student_id')
        queryset = Grades.objects.filter(student_id__in=student_list)

        serializers = GradesSerializer(queryset, many=True)
        return Response(serializers.data)

SQL-запрос, который я пытаюсь создать в Django.

select * from app_grades g
join app_students s on g.student_id = s.student_id
where s.active = true and s.major = 'Art'

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Ваш код будет выполнять два отдельных запроса к базе данных, я предлагаю вместо этого попробовать следующий запрос:

queryset = Grades.objects.filter(student__active=True, student__major='Art')

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

Вы, вероятно, захотите взглянуть на эту часть документации .

Из-за отсутствия модельных отношений, запрещающих использование поисков, я предлагаювы используете Exists подзапрос .В этом конкретном случае запрос будет выглядеть следующим образом:

queryset = Grades.objects.annotate(student_passes_filter=Exists(
    Student.objects.filter(id=OuterRef('student_id'), active=True, major='Art')
)).filter(student_passes_filter=True)

Вам нужно будет импортировать Exists и OuterRef.Обратите внимание, что они доступны в Django 1.11 и далее.

0 голосов
/ 05 марта 2019

Вам, вероятно, следует перегруппировать эти строки, чтобы уменьшить количество запросов:

active_students = Student.objects.filter(active=True)
student_list = active_students.filter(major='Art').values_list('student_id')

Into:

active_students = Student.objects.filter(active=True, major=‘Art’)

И преобразование в список затем

...