gpt4 book ai didi

Django store prefetch_related 结果

转载 作者:行者123 更新时间:2023-12-01 22:22:38 26 4
gpt4 key购买 nike

我知道我可以像这样指定存储 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

是不是和下面的一样?文档说 prefetch_related store 会导致 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?

最佳答案

这两个是一样的

MyClass.objects.prefetch_related('relation')

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

You can use the Prefetch object to further control the prefetch operation (docs)

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

Using to_attr is recommended when filtering down the prefetch result as it is less ambiguous than storing a filtered result in the related manager’s cache (docs)

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

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

关于性能提升

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

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)

关于Django store prefetch_related 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39030198/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com