增强查询集的性能

时间:2019-03-05 01:57:54

标签: python django django-rest-framework django-views

我正在学习DRF并尝试使用查询集。我正在尝试优化以尽可能高效地工作。 目标是获取针对“艺术”专业的在职学生的成绩列表。

基于database optimization技术, 我运行了一些不同的更新,当我查看通过控制台的“网络”选项卡返回的时间时,没有发现差异。但是,我确实做到了,当我在模型过滤上运行.explain()方法时,在Seq扫描中看到的日志更少。 我能做到这一点吗?

例如: 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)

我正在尝试在Django中创建的SQL查询。

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 :(得分:2)

您的代码将执行两个单独的数据库查询,建议您尝试以下查询:

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

此代码将检索完全相同的记录,但仅使用适当的JOIN子句执行一次查询。

您可能想看看this part of the documentation

由于缺少禁止使用查找的模型关系,我建议您使用Exists subuery。在这种特定情况下,查询将如下所示:

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

您将需要导入ExistsOuterRef。请注意,这些功能可从Django 1.11开始使用。

答案 1 :(得分:1)

您可能应该重新组合这些行以减少查询数量:

<?xml version="1.0"?>
<courses>
 <course><courseID>cs601</courseID><courseName>Web Application Development</courseName></course>
 <course><courseId>cs602</courseId><courseName>Server-Side Application Development</courseName></course>
 <course><courseId>cs701</courseId><courseName>Rich Internet Application Development</courseName></course>
</courses>

进入:

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

然后转换为列表