序章


Djangoは、最新のWebアプリを構築するための優れたPythonベースのプラットフォームです。 その最大の強みの1つは、開発者がより速く作業できるようにすることです。

すばらしいアプリを作成してデプロイしました。 物事は素晴らしいですが、今では大量のデータをロードしていて、同時に複数の人に使用させ始めているので、思ったほど速くはありません。

これは一般的な問題です。 幸い、問題を軽減するのに役立つツールがいくつかあります。

まず、より明白な問題のいくつかを確認しましょう。

実際のデータベースを使用する


ローカル開発中、SQLite3に勝るものはありません。 注意しない限り、仮想サーバーでも使用している可能性があります。

SQLite3は、MySQLやPostgreSQLのように複数の同時ユーザーに拡張できません。特に、多くの書き込み操作を実行する操作の場合(セッションを使用している場合は、データベースに書き込みます)。

たとえば512MBのドロップレットなどの低メモリVPSを使用している場合は、MySQLを使用することをお勧めします。 予備のメモリ(2GB以上)がある場合は、PostgreSQLを検討することをお勧めします。これは、多くのDjango開発者に好まれているためです。

デバッグモードを無効にする


ローカル開発を行う場合はデバッグモードが絶対に必要ですが、本番サーバーの速度が低下します。 仮想サーバーのsettings.pyを調べて、DEBUGがFalseに設定されていることを確認します。 また、TEMPLATE_DEBUGもFalseに設定されているか、DEBUGに設定されていることを確認してください。

デバッグツールバーを使用して、パフォーマンスの問題を特定します


本番サーバーではなく、ローカル開発コンピューターで、 Djangoデバッグツールバーをオンにして、特定の問題を特定します。

これを行うには、 django-debug-toolbar モジュールをインストールしてから、次のようにMIDDLEWARE_CLASSESディクショナリにエントリを追加します。

MIDDLEWARE_CLASSES = (
    # ...
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    # ...
)

また、INTERNAL_IPS変数を作成し、IPアドレスを追加する必要があります。 ローカルで開発している場合、IPアドレスはおそらく127.0.0.1であるため、settings.pyに次のような行を追加します。

INTERNAL_IPS = ('127.0.0.1',)

最後に、次のように、INSTALLED_APPSの最後のアイテムとしてdebug_toolbarを追加します。

INSTALLED_APPS = (
    # ...
    'debug_toolbar',
)

インストールドキュメントには、検討する必要のある詳細とオプションの構成オプションが含まれています。

偶然にこれらの変更を本番環境にプッシュしないでください。 (意図的に行う場合は問題ありません)。

これで、サイトを閲覧しているときに、Webページの横に黒いパネルが表示されるはずです。 あなたが統計と数字とあらゆる種類のこっけいな詳細が好きなら、あなたはそれを気に入るはずです。 また、本番サーバーでこれを望まない理由もすぐにわかります。

https://assets.digitalocean.com/articles/scale_django/img1.png ”>

多数のDjangoアプリを構築したので、パネルのSQLセクションに絞り込むことをお勧めします。これは、一般的に懸念される領域だからです。

Djangoの利点/問題の1つは、クエリが実行されるときの関連フィールドの遅延読み込みです。 これは、Djangoが参加を望まないことを意味します。 関連フィールドが必要になった場合、関連フィールドが必要になるたびに追加のクエリが実行されます。

関連するフィールドが必要な場合、これによりn+1個のSQLクエリが発生する可能性があります。 たとえば、Twitterの代替バージョンを作成するとします。 ツイートのモデルを作成し、各モデルはユーザーモデルに関連付けられます。 ホームページには、最新の30件のツイートと、それらを作成したユーザーの名前が表示されます。 これにより、少なくとも31のSQLクエリを実行できます。 ツイートのリストを取得するための1つのクエリと、ユーザー名のルックアップごとに1つのクエリ。

この問題の解決策は、select_relatedです。 これはクエリに対する非常に単純な変更であり、データをフェッチするときにDjangoに結合を実行させます。 関連フィールドが必要であることがわかっているルックアップで使用する必要があります。

次のようにクエリを変更するだけです。

Entry.objects.get(id=5)

このように見えるように:

Entry.objects.select_related().get(id=5)

この機能のドキュメントを読み、必要な場合にのみ使用してください。

要約


私の経験では、上記の問題は多くのサイトの初期パフォーマンスの問題を解決し、最小限のコードと構成の変更ですべて非常に簡単に修正できます。