annotate
Django QuerySetの呼び出しでパフォーマンスの問題が発生しています。私の質問を例で説明しましょう。モデルに次のような外部キー関係があるとします。
def Blog(models.Model):
owner = models.ForeignKey(User)
title = models.CharField()
def BlogArticle(models.Model):
blog = models.ForeignKey(Blog)
title = models.CharField()
body = models.CharField()
timestamp = models.DateTimeField()
ここで、ブログ記事のタイムスタンプに基づいて、最後に更新された 10 件のブログのリストを取得したいとします。私はこれを行うことができます:
latest_updates = Blog.objects.annotate(updated=Max('blogarticle__timestamp')).order_by('-updated')[:10]
これは機能しますが、大量のデータを含む MySQL では速度が低下します (クエリのプロファイリングでは、「tmp テーブルへのコピー」ステップに時間がかかることが示されますが、それは別のトピックです)。
これまでのところ、次のことを検討しました。
- 「updated」
DateTimeField
をBlog
追加し、シグナルまたはオーバーライドを追加して、このフィールドをその の最新のものとsave
同期させます。これはパフォーマンスには優れていますが、DRYの原則に反します。BlogArticle
Blog
BlogArticle
最後の 10 件の更新についてモデルにクエリを実行し、それを使用してモデルにクエリを実行しますBlog
。ただし、これは最後の 10 件の更新がすべて別のブログからのものである場合にのみ機能します。
このクエリを最適化するための他のアイデアはありますか?