我知道我可以指定这样存储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商店会导致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?发布于 2016-08-19 02:53:11
这两个是一样的
MyClass.objects.prefetch_related('relation')
MyClass.objects.prefetch_related(
Prefetch('relation', to_attr='relation_as_list')
)您可以使用预取对象进一步控制预取操作(文档)
只有当您需要细化Prefetch的结果时,才需要prefetch_related对象。例如,您可能需要的不是每个relation,而是特定的,因此您可以细化预取查询。
当筛选预取结果时,建议使用to_attr,因为它比在相关管理器的缓存(文档)中存储筛选的结果更容易混淆。
to_attr没有提供额外的性能提升,它允许减少Prefetch关系的模棱两可,并且可以预取与不同QuerySets相同的关系。
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对象预取相同的关系,那么每个对象都会有一个额外的查询。生成的预取QuerySets将存储在一个列表中,但结果不是您假设为relation_as_list的列表。他们是QuerySets。在您的示例中,可以使用all()来访问这两个关系,比如my_obj.relation_as_list.all()和my_obj.relation.all()。
关于性能提升的
总之,prefetch_related在一个(额外的) DB命中获得了相关对象,这是性能提升的来源。Prefetch对象允许您进一步细化这个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) https://stackoverflow.com/questions/39030198
复制相似问题