2011-07-11 2 views
1

私は、2つのモデルを第3の中間モデルに「関連付ける」2Dテーブルを出力するビューを作成しようとしています。比較的小さなクエリーセットではうまく動作しますが、大きなクエリーセットでは遅くなります。それをスピードアップするためにビューを実装するより良い方法はありますか?どのように2つの関連するモデルを介して "中間"を介して遅いジャンゴビューを改善するには?

シンプルさのために私のモデルとビューの類似バージョンを与えましたが、必要に応じて実際のモデル/ビューを投稿することができます。軽微なエラーが含まれていれば私を許してください。実際のビュー/モデルは機能します。

ありがとうございます。

所望の出力:

 
artist     The Foo Bars  FUBAR  Bas Bix 
Joe Blow     5/10/1975     12/7/2010 
Fred Noname    12/12/2012  10/2/2010 
Smith John    2/2/2002  

類似モデル:

class Person(models.Model): 
    name = models.CharField(max_length=128) 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, through='Membership', related_name="group") 

class Membership(models.Model): 
    person = models.ForeignKey(Person, related_name="membership") 
    group = models.ForeignKey(Group, related_name="membership") 

    date_joined = models.DateField() 
    invite_reason = models.CharField(max_length=64) 

類似のビュー:ビューが遅い出力に基づいている理由

people = Person.objects.all().select_related() 
groups = Group.objects.all().select_related() 
group_names = [group.name for group in groups] 
table = [["artist"] + group_names] 
for person in people: 
    row = [person.name] 
    for group in groups: 
     membership = person.membership.all() & group.membership.all() 
     if membership: 
      membership = membership[0] 
      row.append(membership.date_joined) 
     else: 
      row.append("") 
    table.append(row) 

答えて

1

それは答えることが重要ですプロファイリングやdjango-debug-toolbarなどのツールから。減速のどこがわからなくても、それを修正する方法を伝えるのは難しいです。

このケースでは、私たちはmanytomany関係を扱っているので、減速は膨大な数のクエリに起因すると考えています。これを解決するには、データベース内の何人の人が何人いるかを覚えておく必要があります。要するに、人とグループの間には直接の関係はなく、代わりにメンバーには人とグループの両方がいます。

つまり、select_relatedを使用してクエリの数を減らすことはできません。正しいアプローチは、Personテーブルの代わりにMembershipテーブルをクエリすることになります。正しいアプローチは、あなたの状況の詳細に依存します。あなたが本当に後になっているのがメンバーシップデータであれば、単にMembership.objects.all().select_related()(またはいくつかのバリエーション)に行くことができます。人々のデータの後ろにある場合:

これは、2つのクエリまで数百から数千のクエリを削減します。そのコストは、Pythonコードがやや効率が悪いということです。

私は単純に多くのクエリが問題であると仮定しています。他にも目に見えない大きな問題があるかもしれません。インデックス、CPU集中型Python、非常に大きなテーブルなどを必要とするなど。

関連する問題