2016-08-19 5 views
0

私はこのようなprefetch_relatedの結果を保存するように指定できます。Djangoストア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? 

答えて

0

これら二つはあなたがさらにプリフェッチ動作を制御するためのプリフェッチオブジェクトを使用することができ、同じ

MyClass.objects.prefetch_related('relation') 

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

ある(docs

あなたが必要な場合にのみ、Prefetchオブジェクトが必要ですprefetch_relatedの結果を絞り込みます。たとえば、relationのすべてを必要とせず、プリフェッチクエリを絞り込むことができます。 to_attrを使用

それが関連するマネージャのキャッシュにフィルタリングされた結果を格納する未満あいまいであるとしてプリフェッチ結果をダウンフィルタリングするときには、

to_attr追加の性能ブーストを与えない(docs)が推奨されます関係をあいまいにすることなく、同じ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です。あなたの例では、双方の関係にアクセスすることは prefetch_relatedが1(追加)DBヒットに関連するオブジェクトを取得し、要約するとパフォーマンスが向上

についてmy_obj.relation_as_list.all()my_obj.relation.all()

のように、all()で行うことができますパフォーマンスが向上します。 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) 
関連する問題