使用 JSONField() 优化 API 查询

Optimising API queries using JSONField()

初开:我正在使用postgresql JSONFields.

我的 User 模型中有以下 attribute(字段):

class User(AbstractUser):
   ...
   benefits = JSONField(default=dict())
   ...

我目前基本上使用 DRF 为前端的每个用户序列化利益:

    benefits = UserBenefit.objects.filter(user=self)
    serializer = UserBenefitSerializer(benefits, many=True)

由于底层返回的收益变化小且缓慢,所以我想着"caching"数据库中的JSON每次有变化,提高UserBenefit.objects.filter(user=user)QuerySet的性能.相反,成为 user.benefits 并希望减轻超过 100K+ 用户的数据库负载。


第一个问题:

我应该这样做吗?

第二问:

有没有一种高效的方法可以将对应的serializer.data<class 'rest_framework.utils.serializer_helpers.ReturnList'>写入JSON字段?

我目前正在使用:

data = serializers.serialize("json", UserBenefit.objects.filter(user=self))

第一个问题:

如果您不想使用缓存替代方案,这不是一个坏主意。

如果由于某些更改或......而必须查询数据库并且无法缓存空洞请求,那么保存 JSON 对象的想法可能是个不错的主意。通过这种方式,您只需检索数据并跳过序列化的大部分部分,并终止查询数据透视表 table 以获取 m2m 数据的需要。但也要注意,通过这种方式,您将向行添加一大堆额外数据,除非您大部分时间都需要它们,否则您将获得您并不真正需要的额外数据,您可以提供帮助它在查询集上使用 values 函数,但仍然需要更多编码。基本上,您将为第一次查询使用更多带宽,并使用更多存储空间来存储数据,而不是处理能力。此外,如果您在某些时候需要分页,那么在您的 benefits 上将很难实现。

获取 m2m 关系数据通常非常快,具体取决于数据库中的数据量,但获得更好性能的最终方法是缓存请求并尽可能减少数据库命中。

正如您可能经常听到的那样,您应该根据您的要求和限制进行测试和基准测试,看看哪些选项最适合您。在不了解整个范围和当前解决方案的信息的情况下,很难提出优化方法。

关于你的第二个问题:

我想我不太明白。如果要存储 JSON 对象,它是 User 模型中的一个字段,那么为什么需要 data = serializers.serialize("json", UserBenefit.objects.filter(user=self))

您不需要它,因为序列化器可以 return JSON 字段数据。