使用Django ORM预取间接相关的项目

时间:2019-04-19 07:33:17

标签: django query-optimization django-orm

我正在尝试针对我的审核系统(使用Django和DRF构建)优化查询。 我目前一直坚持重复检索:目前,我有

之类的东西
class AdminSerializer(ModelSerializer):
    duplicates = SerializerMethodField()

    def get_duplicates(self, item):
        if item.allowed:
            qs = []
        else:
            qs = Item.objects.filter(
                    allowed=True, 
                    related_stuff__language=item.related_stuff.language
                ).annotate(
                    similarity=TrigramSimilarity('name', item.name)
                ).filter(similarity__gt=0.2).order_by('-similarity')[:10]
    return AdminMinimalSerializer(qs, many=True).data

可以正常工作,但是对要显示的每个项目至少执行一个附加查询。另外,如果有重复项,我将进行其他查询以填充AdminMinimalSerializer,其中包含重复项的字段和相关对象。我可以通过在序列化程序中使用prefetch_related来减少开销,但这不会阻止我对每个项目进行几个查询(假设我只有一个相关项目要在AdminMinimalSerializer中预取,我d仍然有〜2N + 1个查询:1个项,N个重复项,N个相关项重复项。

我已经看过Subquery了,但是我无法检索对象,只能检索一个id,在我看来,这还不够。我尝试在Prefetch对象和.annotate中使用它。

我也尝试过类似Item.filter(allowed=False).prefetch(Prefetch("related_stuff__language__related_stuff_set__items", queryset=Items.filter..., to_attr="duplicates"))的操作,但是duplicates属性已添加到“ related_stuff__language__related_stuff_set”中,所以我不能真正使用它...

我欢迎任何想法;)

0 个答案:

没有答案