2011-08-17 16 views
1

私はDjangoアプリにManyToManyフィールドを持つItemモデルを持っています。このモデルは中間のお気に入りモデルで処理されます。問題のモデルの簡略化したバージョンを次に示します。Django:関連フィールドのカウントに基づいてQuerySetを注文する最速の方法は何ですか?

class Item(models.Model): 
    name = models.CharField(max_length=200) 

class Favorite(models.Model): 
    user = models.ForeignKey(User) 
    item = models.ForeignKey(Item) 

お気に入りの数で注文した商品のリストを取得しようとしています。以下のクエリは機能しますが、Itemテーブルには何千ものレコードがあり、クエリを完了するまで数分かかることがあります。これは、潜在的な解答に関連しているが、私は使用して結果をページ付けてる場合

items = Item.objects.annotate(num_favorites=Count('favorite')).order_by('-num_favorites') 

わからないDjangoのビルトインPagintor:私は私の項目にfavoritesフィールドを追加することができます知っている

paginator = Paginator(items, 100) 

をモデルとインクリメントを追加することができますが、合理的な時間にこのデータを取得するための、よりクリーンで効率的な方法があるのだろうかと思います。

+----+-------------+--------------------+------+-----------------------------+-----------------------------+---------+-------------------------------+------+---------------------------------+ 
| id | select_type | table    | type | possible_keys    | key       | key_len | ref       | rows | Extra       | 
+----+-------------+--------------------+------+-----------------------------+-----------------------------+---------+-------------------------------+------+---------------------------------+ 
| 1 | SIMPLE  | appname_item  | ALL | NULL      | NULL      | NULL | NULL       | 566 | Using temporary; Using filesort | 
| 1 | SIMPLE  | appname_favorite | ref | appname_favorite_67b70d25 | appname_favorite_67b70d25 | 4  | appname.appname_item.id  | 1 |         | 
+----+-------------+--------------------+------+-----------------------------+-----------------------------+---------+-------------------------------+------+---------------------------------+ 

答えて

1

インデックスが定義されていないorder_by句を使用しようとすると、そのインデックスが定義されます。インデックス処理が速くなります。インデックスは 'num_favorites'になります。実行時間。あなたが使っているテクニックもうまくいきます。それに何も悪いことはありません。

related questionを参照してください。同じ問題で私から尋ねられたsaverioは、この問題に対処するための優れた答えを示しました。お役に立てれば。

+0

@Aamirに感謝していますが、今はもうこれを調べる機会がありました。私はあなたの質問への答えを見て、しかし私は持っている問題にそれを適用する方法がわかりません。これに関するMySQLのドキュメントはかなり疎そうです。上記の質問にEXPLAINの出力を追加しました。あなたはそれが意味するものとその修正方法を理解する助けになると思いますか?ありがとう! –

1

すでに最良の方法である:以下

は、MySQL EXPLAIN関数の出力です。遅い場合は、データベースに問題がある可能性があります。具体的には、そのクエリに適切なインデックスがないため、データベースがあまりにも多くの並べ替えを行う必要があります。

Djangoのデバッグツールバーは、このようなことを診断するのに最適です。各クエリの実行時間が表示され、それぞれのEXPLAIN機能を実行できます。 MySQLのドキュメントは、EXPLAINの出力の意味を教えてくれます。しかし、それ以降はdbを最適化するのはあなた次第です。

+0

@Danielに感謝します。私はもう少し前に+1しましたが、今はこれを調べる機会がありました。私はEXPLAINを実行して、クエリが正しく実行されていないことを出力から知ることができますが、それを修正する手掛かりはありません。私はEXPLAINでMySQLのドキュメントを読んだことがありますが、あまり役に立ちません(私はこのページを読んで再読しました:http://dev.mysql.com/doc/refman/5.0/en/using -explain.htmlとそれが参照するものはそれほど役に立ちませんでした)。 EXPLAINの出力を私の質問に追加しました。それを解読する手助けができると思いますか?ありがとう! –

関連する問題