2017-11-14 17 views
0

私は、QuerySetsが怠け者であり、いつもデータベースにぶつかるのを避けるために特定の条件でのみevaluatedであることを知っています。Django QuerySetチェイン、サブセット、キャッシング

一般的なクエリセット(すべてのアイテムを取得)が設定されていて、それを使用してより洗練されたクエリセット(フィルタを追加するなど)を作成すると複数のSQLクエリにつながるかどうかはわかりません。

例:

all_items = MyModel.objects.all() 
subset1 = all_items.filter(**some_conditions) 
subset2 = subset1.filter(**other_condition) 

1)が、これは3種類のSQLクエリを作成しますか? 3つの変数が評価されるかどうか(たとえば、反復するかどうかなど)はすべて異なりますか?

2)は、この効率的ですかリストに変換し、その後、すべてのアイテムを取得し、Pythonでそれらをフィルタリングする方が良いでしょうか?

+0

あなたはデータへのアクセスを開始する場合にのみこれは、データベースにヒットします。 –

+1

サブセット2にしかアクセスできないとします。 – Leonardo

答えて

0
  1. はい。これは3つの異なるSQLクエリです。 (あなたが3つの異なるオブジェクトを使用するので:all_items,サブセット1,サブセット2)。あなたが複数の条件を持っている場合は、同じオブジェクト上で複数のquerues

    q = Entry.objects.filter(headline__startswith="What") 
        q = q.filter(pub_date__lte=datetime.date.today()) 
        q = q.exclude(body_text__icontains="food")<br> 
    


2を加えた場合

all_items = MyModel.objects.all() 
subset1 = all_items.filter(**some_conditions) 
subset2 = subset1.filter(**other_condition) 


クエリセットは遅延しているリストにそれらを入れてのようなものを使用します。 MyModel.objects.filter(reduce(operator.or_, [Q(some_model__icontains=item) for items in conditionList]))

これは必須ですあなたが唯一の最後のクエリは一つだけのデータベースクエリ要求が実行され、その後subset2を設定する列挙した場合)

import operator 
from functools import reduce 
from django.db.models import Q 
+0

1)それを修正するか説明する。 2)あなたが前の問題を修正するならば、私はあなたに投票することができます。考えられる問題は、関連するフィールド 'some_model__related_model = value'上の条件と組み合わせることです。フィルタは問題ありませんが、追加のクエリを追加するリスクなしに、後でサブセットに分割するのは一般的ではありません。 select_relatedまたはannotateが必要な場合があります。最後はDRYコードではありません。 – hynekcer

+0

同じオブジェクトに対していくつかのクエリを実行すると、QuerySetsは遅延します。q = Entry.objects.filter(headline__startswith = "What")q = q.filter(pub_date__lte = datetime.date.today()q = q.exclude(body_text__icontains = "彼は3つの異なるオブジェクトに照会しました。 'all_items = MyModel.objects.all() subset1 = all_items.filter(** some_conditions) subset2 = subset1.filter(** other_condition)' – FirePower

+0

@Leonardo不明な質問があります簡単な答えはありません。彼はたぶんクエリ=データベースへの要求を理解しています。彼は3つのクエリの結果を決して使用しません。場合によります。正解は3か2か1であることができます。 QuerySetは、データベースに実際にアクセスしなくても、クエリーセットを作成し、渡したり、他のQuerySetsと組み合わせたりすることができます。 (docs) – hynekcer

0

1をインポートするには、それが最適です。

2)大部分のアプリケーションコードが書き込まれた後、適切な量のデータを測定する前に、早すぎる最適化を避けます。データベースが大きくなると、最終的に最も重要な問題は何か分かりません。例えば。サブセットを要求すると、通常はデータベースにキャッシュされるため、クエリが高速になります。メモリの量は他の最適化とは対照的です。たぶん、メモリ内のすべてのデータを後で保持することはできず、ユーザーはデータのページだけでアクセスします。きれいな読み取り可能なコードは、後で続けることができるように後で削除する必要がある20%の最適化より後の可能な最適化にとって重要です。クエリの(遅延)評価について

その他の重要な段落:
When QuerySets are evaluated
QuerySets are lazy
Laziness in Django