5

いくつかの信号を作成しましたpost_saveが、後でパフォーマンスの問題が発生するかどうか疑問に思っていました. たとえば、次のようなものがあります。

def my_signal(sender, **kwargs):
  # some minimal processing
  posts = len(MyPosts.objects.filter(date__gte=variable))
  if entries == "20":
    # crate an object and assign it to the post's author.


post_save.connect(my_signal, sender=MyPosts)

非常に忙しいサイトがあり、投稿が作成されるたびにこれが起動しているとしましょう。パフォーマンスが悪すぎますか?より遅いペースでシグナルを発する方法はありますか (おそらく、1 日 1 回またはいくつかのリクエストごとに)。

更新

もう 1 つの質問: Django は.save()呼び出しとpost_saveシグナルを 1 つのデータベース リクエストに合成するほどスマートですか、それともここでいくつかのリクエストを実行していますか?

ありがとう!

4

2 に答える 2

13

シグナルハンドラーのパフォーマンスへの影響は、もちろんその機能によって異なります。ただし、シグナルが発生したときに同期的に実行されるため、ハンドラーで多くのアクションが実行されている場合(たとえば、データベース呼び出しが多い場合)、実行が遅れることに注意する必要があります。

Django自体は、シグナルハンドラーを統合する別の機会を提供しませんが、必要に応じて、たとえばシグナルハンドラー内から非同期でタスクを呼び出すことができるdjango-celeryを調べる必要があります...

于 2012-05-31T19:55:57.753 に答える
8

シグナルが同期的に実行される場合、シグナルのパフォーマンスは、接続しているハンドラーの数と、呼び出されたときにそれらが実行するコードに大きく依存します。post_save元の挿入/更新クエリは、シグナルが発生したときにすでに実行されています。クエリを実行する前にモデルデータに変更を加える場合は、pre_save代わりにハンドラーで変更できます。場合によっては、データベーストリガーで処理することもできます。

いいえ、Djangoは、任意の数の接続されたPython関数で実行される可能性のあるクエリを1つのクエリに結合するのに「十分」ではありません。また、ユースケースで説明されているように、更新/挿入を複数のテーブルに挿入する可能性がある場合は、更新/挿入を1つのクエリに結合することもできません。ただし、Djangoは単一のトランザクション内でこれらを処理できます。

django-celery、django-ztask、taskmasterなどは、要求/応答サイクルの外部で処理する必要があるより複雑なタスク用に設計されています。1日に1回または2回だけ実行する必要があるタスクの場合は、カスタム管理コマンドを記述してcronを使用することもできます。

于 2012-06-05T18:13:25.810 に答える