Brownfieldプロジェクトにおける非効率的なDjango‐ORMの定着


つの最大の勝利は、Jjangoアプリの速度を向上させるための“Oopsは”非効率的なデータベースを意味していないことを意味するコードベースは、長年にわたって気付かれなかった.実際、CodeBaseが成熟し、チームメンバーが変更され、コード収集集塵の古い非効率なORMクエリを見落とすことができます.以下のような単純なORMクエリ
def check_hounds():
    queryset = HoundsModel.objects.all()
    if len(queryset) > 2:
         return "oh no. Run!" 
これは、データベースからすべてのレコードを読んで、アプリケーションレベルでチェックしています.より効率的
def check_hounds():
    if HoundsModel.objects.count() > 2:
         return "oh no. Run!" 
そのような非効率では、簡単に話すことができます.「そんなことはしない.よく、たぶんない.しかし、締め切りを満たすために急いでいた過去のいくつかのdevについては、11 PMのコードの校閲者は同様にクランチ時間中にコーヒーに生き残るか?そして、あなたは今、そのコードの責任がある!
わずかに少ない教科書だけでなく、両方の見栄えと改善に簡単です
def write_condolence_letters(visited_coops):
    queryset = ChickenModel.objects.all()
    for chicken in queryset:
        if chicken.coop.pk in visited_coops:
            return f"dear {chicken.coop.owner_name}..."
        else:
            ...
スポットの問題?さて、all()以上のループは、1つの行くのDBからすべてを読み取ります.何十億もの鶏がいるならば、パフォーマンス問題を予想してください.そのために、 iterator() を使用して、一度にDBから引いたREAD 2000 (デフォルト)レコードをチャンクできます.また、chicken.coop.pkは、デフォルトでlazily evaluatedであるため、それぞれのニワトリに対して追加のデータベースを読み込みます.coopは、chicken.coopを経由してアクセスされたときにDBから読み込まれます.この特定のフィールドのために、我々はDJangoのフィールドキャッシングを使用することができます.したがって、
def write_condolence_letters(visited_coops):
    queryset = ChickenModel.objects.all()
    for chicken in queryset.iterator():
        if chicken.coop_pk in visited_coops:
            return f"dear {chicken.coop.owner_name}..."
        else:
            ...
私たちがPK以外の関連モデルの分野で働いているならば、どうですか?確かに_idは我々のためにDjangoによってつくられます、しかし、我々がcoop_pkのような他のフィールドにアクセスする必要があるならば、どうですか?そのためには、 chicken.coop.owner_name または select_related を使用します(これがフォリグキーやonetooneなどの関係ならば)
def write_condolence_letters(visited_coops):
    queryset = ChickenModel.objects.all()
    for chicken in queryset.select_related('coop'):
        if chicken.coop.pk in visited_coops:
            return f"dear {chicken.coop.owner_name}..."
        else:
            ...
現在、prefetch_relatedは、coopと同じ読みの間に引き出されます.chickenはもはや使用されませんが、イテレータがiteratorselect_relatedで役に立たないので、prefetch_relatedは彼らの影響を無効にします.それで、これらは相互に排他的であるので、文脈だけで、我々は本当にどんなパフォーマンス改善戦略が必要であるかについて、本当に言うことができます.

あなたのCodeBaseは古い非効率のORMルックアップを持っていますか?


これは、コードのレビュー中に新しい効率的なORMのルックアップを見つけるのは簡単ですが、すでにどのようなコードベースでは?私はdjango.doctorであなたのためにそれをチェックすることができます、あるいは、review your GitHub PRs

またはDjango refactor challengesを試してみてください.