3

annotate() がクロールを遅くするのは正常ですか?

次のように注釈を使用します。

post_list = j.post_set.all().annotate(num_comments=Count('comment')).order_by('-pub_date')

注釈を実行しない場合の 4 倍の時間がかかるようにしました。

post_list = j.post_set.all().order_by('-pub_date')

values() と defer() でも試しましたが、どちらも役に立ちませんでした。コメント数を Post テーブル内のフィールドとして保持する唯一の現実的なオプションはありますか?

ちなみにMySQLを使っています。

4

4 に答える 4

3

私はこれが遅いことを知っていますが、行ってみてください:

j.post_set.all().extra({'num_comments': 'SELECT COUNT(*) FROM Comment WHERE Comment.post_id = post.id'}).order_by('pub_date')

(テーブル名を変更)

少なくともpostgres 9.2以降では、注釈を使用するよりもはるかに高速なクエリを生成します。

Annotate は、左外部結合を使用してからグループ化して最終結果を生成しようとしますが、上記の余分な句は、選択された列の 1 つにサブクエリを追加します。後者は、データベースが既存のデータベース インデックスをより有効に活用できるようにします。

于 2014-03-08T10:50:20.557 に答える
1

したがってpost_list = j.post_set.all().order_by('-pub_date')、単一のテーブルのデータベースに対してクエリを実行しているという単純なケースです。これは高速になり、フィールドにインデックスを追加するとさらに高速になりpub_dateます。ordering = ['-pub_date']Post の Meta セクションに設定します。

注釈としてより複雑なケースでは、要求するレコードごとに、関連するテーブルでルックアップを実行し、返されたエントリの数をカウントする必要があります。インデックスからデータを直接取得している場合でも、単純なケースよりも必然的に時間がかかります。

トラブルシューティングについては、 をインストールし、そのdjango-debug-toolbarクエリ タブを調べて、速度を低下させているクエリを見つけ、explainツールを実行して速度を低下させている原因に関する追加情報を取得することをお勧めします。このツールは、生成された正確な SQL と、クエリのどの部分が最も「コストがかかる」かを示します。

クロールが遅くなる場合は、この情報をキャッシュに保存することを検討する必要があります。または、この種のメタ情報をカスタム インデックスに格納できる postgres などのデータベースを使用します。

于 2013-07-08T01:36:57.077 に答える
1

私はこれが少し遅れていることを知っていますが、Count() で同様の問題を解決しようとしてここに行き着きました。私は、シェルを使用してどの SQL が実行されているかを調べるという Matthew Schinckel のアイデアを使用しました。次に、pgAdmin を開き、クエリを貼り付けて実行しました。驚いたことに、クエリの実行は、私の Django アプリにかかる時間の大部分を占めていました。

私のアプリはジオメトリ フィールドで動作しますが、クエリセットに必要なフィールドをリストしないことで、Group By 句にすべてのテーブル フィールド (非常に大きな geom フィールドを含む) が含まれていました。

QuerysetAPIリファレンスを確認した後、フィールドの短いリストを使用してクエリセットに .Values() を含めました。これにより、クエリ時間が 5 秒から約 10 ミリ秒に短縮されました。

于 2015-11-24T19:53:22.897 に答える