Django休息框架db查询速度慢

时间:2015-07-21 07:31:57

标签: django serialization query-optimization django-rest-framework django-queryset

  • 我有一个带有16个DecimalFields的Django模型。
  • 我创建了一个 ListAPIView用于获取此数据。
  • 使用此模型的约5000个实例 在我的数据库中,对这个api视图的GET请求超过15 秒。

型号:

class MyModel(models.Model):
    f1 = models.DecimalField (max_digits=8, decimal_places=3)
    f2 = models.DecimalField (max_digits=8, decimal_places=3)
    f3 = models.DecimalField (max_digits=8, decimal_places=3)
    f4 = models.DecimalField (max_digits=8, decimal_places=3)
    f5 = models.DecimalField (max_digits=8, decimal_places=3)
    f6 = models.DecimalField (max_digits=8, decimal_places=3)
    f7 = models.DecimalField (max_digits=8, decimal_places=3)
    f8 = models.DecimalField (max_digits=8, decimal_places=3)
    f9 = models.DecimalField (max_digits=8, decimal_places=3)
    f10 = models.DecimalField (max_digits=8, decimal_places=3)
    f11 = models.DecimalField (max_digits=8, decimal_places=3)
    f12 = models.DecimalField (max_digits=8, decimal_places=3)
    f13 = models.DecimalField (max_digits=8, decimal_places=3)
    f14 = models.DecimalField (max_digits=8, decimal_places=3)
    f15 = models.DecimalField (max_digits=8, decimal_places=3)
    f16 = models.DecimalField (max_digits=8, decimal_places=3)

串行:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel

我没有对数据进行任何过滤。当我在django shell中运行查询时,它会在几毫秒内运行。我假设序列化是这里的问题。但是,我使用的是默认的ModelSerializer。

所有这些字段都在同一个表格中,所以我看不出这里会出现N + 1问题。

如何进一步说明此问题?我应该期望我的查询在这么多模型实例中变慢吗?

3 个答案:

答案 0 :(得分:0)

这是因为串行器,您可以使用Model.objects.values()使用序列化器来提高性能,这将非常快速地返回相同的数据。

答案 1 :(得分:0)

安装django-toolbar并查看查询时间和CPU时间。如果查询花费时间并且正在进行一些延迟加载检查prefetch_related& select_related

答案 2 :(得分:0)

而不是使用ListAPIView尝试使用ModelViewSet代替。

为自己创建一个仅继承ListModelMixin

的自定义视图集
class ListModelViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    pass

现在将其扩展到您的视图集并在那里写下queryset

def get_queryset(self):
    Model.objects.all()

这不是一个可以加速事情的逻辑,因为最终所有这些都继承了相同的东西,但值得一试。

如果这也不起作用......另一个可能的原因可能是5000个对象是一个非常大的数字。 Shell不会立即返回所有对象。它对Model.objects.all()执行查询,但是将对象数量限制为20,然后将此....(其余元素截断)....,所以我猜这减少了与Web视图相比的时间何时必须将所有元素都列入清单。