【问题标题】:Optimization Django ORM优化 Django ORM
【发布时间】:2021-03-02 18:47:14
【问题描述】:

我正在运行我自己的智能家居项目,在树莓派上使用带有 MySql 的 django 后端。我在数据库中有 SensorsData 表,其中包含来自传感器的数据的数千条记录。在我的 REST API 中,我使用的视图如下所示:

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def list_of_sensors_data(request, format=None):
    """
    Get list of all sensors data, only for authenticated users
    :param request: GET
    :return: list of all sensors data if ok http 200 response
    """
    sensors_data = SensorsData.objects.all()
    serializer = SensorsDataSerializer(sensors_data, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)

我已经使用 locust 运行了性能测试,模拟了 10 个尝试使用我的端点的用户。一段时间后,Django 使用这个特定的端点不断返回 504 Timeout。我的任务是,如何优化这个查询集?我需要让它更快。

EDIT Sensors数据模型:

class SensorsData(models.Model):
    sensor = models.ForeignKey(Sensors, on_delete=models.CASCADE)
    delivery_time = models.DateTimeField(auto_now_add=True)
    sensor_data = models.CharField(max_length=20)

    class Meta:
        verbose_name = "Sensor data"
        verbose_name_plural = "Sensors data"

    def __str__(self):
        return f"{self.sensor.id}: {self.sensor.name}"

SensorsData 序列化器:

class SensorsDataSerializer(serializers.ModelSerializer):
    sensor = serializers.SlugRelatedField(read_only=False, many=False, slug_field='name', queryset=Sensors.objects.all())

    class Meta:
        model = SensorsData
        fields = ("sensor", "delivery_time", "sensor_data")

【问题讨论】:

  • 仅适用于当前经过身份验证的用户?或者 users(?) 可以从 request.user 获取当前认证用户
  • 请分享SensorDataSerializerSensorData 模型。
  • @Alvi15 ofc 测试针对经过身份验证的用户运行。
  • @MichałZaręba: sensors_data = SensorsData.objects.select_related('sensor')

标签: mysql django optimization raspberry-pi django-queryset


【解决方案1】:

这将引入一个N+1 问题,对于每个SensorsData 对象,您将进行额外的查询以获取相关的Sensor 对象。好消息是您可以使用.select_related(…) [Django-doc] 让 Django 在同一个查询中检索所有相关的sensors:

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def list_of_sensors_data(request, format=None):
    sensors_data = SensorsData.objects.select_related('sensor')
    serializer = SensorsDataSerializer(sensors_data, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)

【讨论】:

    猜你喜欢
    • 2019-08-15
    • 2021-06-16
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 2018-04-03
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多