Django ソースを見ると、ManyToManyField への割り当て時に、新しい値が追加される前に既存の値がすべて削除されていることがわかります。
https://github.com/django/django/blob/master/django/db/models/fields/related.py#L776
この素朴なアルゴリズムは、私のアプリケーションを実行すると、膨大な量のデータベース チャーンを引き起こします。一度に何十万もの関係を更新します。
私の場合、これらの更新のほとんどは noops になるため (つまり、現在の値と新しい値が同じになる)、追加する必要があるオブジェクトを最初にチェックするアルゴリズムで M2M フィールドを更新することで、チャーンを簡単に減らすことができます。次に、どれを削除する必要があるかを確認します。
これは、これを行うための再利用可能な関数が既に存在するかどうか疑問に思っているほど一般的なパターンのようです。