【问题标题】:How to optimize Django API Query如何优化 Django API 查询
【发布时间】:2021-08-24 20:48:22
【问题描述】:

如何优化我的 api View 或 Serializer ?执行任务需要 3 分钟以上。我认为这是由于外键字段,但即使我在序列化程序字段上检索它们,它仍然运行缓慢。

api/View.py

@api_view(['GET', 'POST'])
def edge_list(request):
    """
    List all edges of all networks, or create a new edge.
    """
    if request.method == 'GET':
        edges = Edge.objects.all()
        context = {'request': request}  # for filtering by field in url
        serializer = EdgeSerializer(edges, many=True, context=context)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = EdgeSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.error, status=status.HTTP_400_BAD_REQUEST)

api/serializers.py

class EdgeSerializer(DynamicFieldsMixin, serializers.ModelSerializer):

    class Meta:
        model = Edge
        fields = (
            'id', 'edge_id', 'name', 'length', 'speed',
            'lanes', 'param1', 'param2', 'param3', 'network',
            'road_type', 'source', 'target'
            )

api/models.py

class Edge(models.Model):
    network = models.ForeignKey(RoadNetwork, on_delete=models.CASCADE)
    source = models.ForeignKey(Node, related_name='source',
                               on_delete=models.CASCADE,
                               help_text='Source node of the edge',
                               )
    target = models.ForeignKey(Node, related_name='target',
                               on_delete=models.CASCADE,
                               help_text='Target node of the edge',
                               )
    road_type = models.ForeignKey(RoadType, on_delete=models.CASCADE,
                                  help_text='Roadtype of the edge'
                                  )
    edge_id = models.PositiveBigIntegerField(db_index=True)
    name = models.CharField(max_length=80, blank=True, help_text='Name of the edge')
    geometry = models.LineStringField()
    length = models.FloatField()
    speed = models.FloatField(null=True, blank=True)
    lanes = models.SmallIntegerField(null=True, blank=True)
    param1 = models.FloatField(null=True, blank=True)
    param2 = models.FloatField(null=True, blank=True)
    param3 = models.FloatField(null=True, blank=True)

    def __str__(self):
        return self.name or 'Edge {}'.format(self.edge_id)

【问题讨论】:

    标签: django api django-models django-rest-framework django-views


    【解决方案1】:

    是的,您正在执行 N*3+1 个查询。

    代替

    edges = Edge.objects.all()
    

    试试

    edges = Edge.objects.select_related('network', 'source', 'target').all()
    

    在一个查询中获取所有这些外键字段。

    你也可以试试

    edges = Edge.objects.prefetch_related('network', 'source', 'target').all()
    

    用于三个查询(冗余数据可能更少)。

    【讨论】:

    • 谢谢。我试过这个,但它并没有改变什么。它仍然很慢。
    • @aba2s 然后打开分析器。我最好的下一个猜测是 JSON 序列化需要一些时间。
    猜你喜欢
    • 2011-10-08
    • 2012-03-19
    • 1970-01-01
    • 2023-03-30
    • 2023-03-25
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多