クロールにあなたのウェブサイトを遅らせることができるジャンゴ機能
5677 ワード
order_by
を通してDjango QuerySetを注文すると、DJangoは、指定された列で行を注文するようにデータベースに依頼します.命令されている行数があまり大きくない限り、この操作は速くなければなりません.しかし、
order_by
でビルドを使用すると、非常に高価で低速な操作の一連を引き起こすことができます.データベースからランダム行を取得します.非ランダムに1つのランダム行を読む
ランダムな記録を得る方法でのDjangoの造りは、
order_by('?')[0]
を通してあります.Djangoドキュメント自身がthis warningを与えるという点に注意してください:
order_by('?')
queries may be expensive and slow
パフォーマンスが悪いのは、djangoが以下の非効率的なSQLを生成するという事実です.
SELECT * FROM entry ORDER BY RAND() LIMIT 1
SQLを壊しましょう.SELECT * FROM entry
これは、entry
テーブルからすべての列を含むようにデータベースに指示します.ORDER BY RAND()
これは、データベースに対して、行ごとに乱数を生成するように指示します(使用するデータベースによって異なります.LIMIT 1
これは、最小の1つの生成された番号をスキャンするデータベースを教えてください.この行を読み込む.そのシンクを入れてください:我々が100000の行を持っているならば、100000の乱数は最初に生成されます.乱数を生成するのは遅いです、スキャンは迅速ではありません.遠近法のためにこの操作はマイニングBitcoinのように多くのにおいがする最終的にすべての私たちはそれを取得するデータベースから1行を読んでいる!小さな給料でたくさんの仕事をしなければならない.
データベースに多くの行があって、
order_by('?')[0]
が使われるならば、悪いパフォーマンスを予想してください.つのランダム行を効率的に読む
要するにデータベースはランダムではない.アプリケーションもあります.したがって、データベースとアプリケーション間の分割の責任を考慮します.
データベースレベルの
アプリケーションレベルの
そのことを念頭に置いて、Django Doctorがプル・リクエストを見直したときにこのアドバイスを与えている理由です.
自己
このようにカスタムモデルマネージャにロジックを移動させることで、ソリューションの階層化を改善することを考えてください.
from random import randint
from django.db import models, transaction
class RandomManager(models.Manager):
@transaction.atomic
def random(self):
index = randint(0, self.count()-1)
return self.all()[index]
class Entry(models.Model):
objects = RandomManager()
random_item = Entry.objects.random()
カウントと行の両方が同じトランザクションで起こるようにするために order_by('?')[0]
の使用に注意してください.transaction.actomic
が起こることができました.あなたのDjango Codebaseは、このように技術負債を持ちますか?
Django Doctorを見つけることができると一般的なジャンゴ技術の債務の40種類以上を修正し、あなたのためにもreview your GitHub Pull Requestsすることができます.
Reference
この問題について(クロールにあなたのウェブサイトを遅らせることができるジャンゴ機能), 我々は、より多くの情報をここで見つけました https://dev.to/codereviewdoctor/the-django-feature-that-can-slow-your-website-to-a-crawl-2f9kテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol