【问题标题】:Django store prefetch_related resultDjango 存储 prefetch_related 结果
【发布时间】:2016-08-19 02:23:49
【问题描述】:

我知道我可以指定这样存储 prefetch_related 的结果。

 my_objs = MyClass.objects.prefetch_related(
     Prefetch('relation', to_attr='relation_as_list')
 )

 for my_obj in my_objs:
     l = my_obj.relation_as_list

和下面的一样吗? Doc 说 prefetch_related 存储会导致 Queryset,而我没有得到性能提升的地方?

 my_objs = MyClass.objects.prefetch_related('relation')

 for my_obj in my_objs:
     l = list(my_obj.relation.all())  # looks like DB hit but it isnt?

【问题讨论】:

    标签: django prefetch


    【解决方案1】:

    这两个是一样的

    MyClass.objects.prefetch_related('relation')
    
    MyClass.objects.prefetch_related(
       Prefetch('relation', to_attr='relation_as_list')
    )
    

    您可以使用 Prefetch 对象进一步控制预取操作 (docs)

    只有在需要细化prefetch_related 的结果时才需要Prefetch 对象。例如,您可能不需要每个relation,而是需要特定的,因此您可以优化预取查询。

    建议在过滤预取结果时使用 to_attr,因为它比将过滤结果存储在相关管理器的缓存中更不模糊 (docs)

    to_attr 不会提供额外的性能提升,它允许使Prefetch 关系不那么模糊,并且可以使用不同的查询集预取相同的关系。

    MyClass.objects.prefetch_related(
       Prefetch('same_relation', queryset=queryset_one, to_attr='relation_set_one')
       Prefetch('same_relation', queryset=queryset_two, to_attr='relation_set_two')
    )
    

    如果您使用不同的Prefetch 对象预取相同的关系,则每个对象都会有一个额外的查询。生成的预取 QuerySet 将存储在一个列表中,但结果不是您假设为 relation_as_list 的列表。它们是查询集。在您的示例中,可以使用all() 访问这两个关系,例如my_obj.relation_as_list.all()my_obj.relation.all()

    关于性能提升

    总之,prefetch_related 在一个(额外的)数据库命中中获取相关对象,这是性能提升的来源。 Prefetch objects 让您可以进一步细化这个 DB 调用。

    for item in yourmodel.object.all():
        for a_relation in item.relation.all():
            do_something(a_relation)  
            # WITHOUT PREFETCH RELATED YOU'D HIT DB EVERY TIME!! 
            # IMAGINE IF YOU HAD TONS OF ITEMS
    
    # THIS WILL HAVE 2 DB HITS
    for item in yourmodel.object.prefetch_related('relation').all().:
        for a_relation in item.relation.all():
            do_something(a_relation)  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-25
      • 2020-07-12
      • 1970-01-01
      • 2014-10-12
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      相关资源
      最近更新 更多