Django 我能再喝点好的吗?

new9mtju  于 2023-03-04  发布在  Go
关注(0)|答案(1)|浏览(65)

这与上一个问题有关:* * 一个
但这里是MemosInProduct模型的一些变化:

class MemosInProduct(models.Model):
    product_key=models.ForeignKey(ProductInOrder, on_delete=models.CASCADE, related_name="product_key")

    memo=models.CharField(max_length=100)

    _is_deleted=models.BooleanField(default=False)
    blahblah some codes...

软删除功能需要添加"_is_deleted"字段。
除MemosInProduct外,所有模型定义和查询目标均与前面的问题相同。这意味着我钢需要所有OrderList数据以及与之相结合的所有相关数据(产品、备忘录):* * 除外**
订单列表[0].订单关键字[0].产品关键字[0].备注订单列表[0].订单关键字[0].产品关键字[1].备注订单列表[0].订单关键字[1].产品关键字[0].备注...
这是这个问题的开始:我意识到需要过滤一个特定的表。这意味着,我只需要做过滤MemosInProduct表。
接受Almabud的答案,我尝试了许多orm查询,最后得到:

OrderList.object.prefetch_related(
            Prefetch('order_key', queryset=ProductInOrder.object.prefetch_related(
                Prefetch('product_key', queryset=MemosInProduct.object.all().filter(_is_deleted=False))).all()
            )
        ).all()

它符合我的目标。所有的OrderList和ProductInOrder都显示得很好,但只有MemosInProduct表有filterd。
但是我想知道这个查询优化了没有。至少,我想知道这个查询没有N +1个问题。
此外,如果您能让我知道查询是否有其他改进,我将不胜感激。
感谢您阅读这个冗长问题。

l5tcr1uw

l5tcr1uw1#

另一种方法是使用独立的Prefetch,因此两种方法是:

嵌套预取:
OrderList.object.prefetch_related(
    Prefetch(
        'order_key',
        queryset=ProductInOrder.object.prefetch_related(
            Prefetch(
                'product_key',
                queryset=MemosInProduct.object.filter(_is_deleted=False)
            )
        )
    )
)
独立预取:
OrderList.object.prefetch_related(
    'order_key',
    Prefetch(
        'order_key__product_key',
        queryset=MemosInProduct.object.filter(_is_deleted=False)
    )
)

这两种方法在避免N+1问题的同时将产生相同的结果。但是,使用独立预取可能比使用嵌套预取提供稍好的性能。原因是在嵌套预取方法中,为每个ProductInOrder行创建不同的查询集。ORM应“合并”这些查询集以避免N+1问题。该过程需要额外的计算资源(取决于要合并的查询集的大小和复杂度)。

相关问题