Джанго очень медленный - PullRequest
       11

Джанго очень медленный

6 голосов
/ 06 ноября 2010

Некоторые профилирования показывают, что отрисовка шаблона является виновником. (Я пробую страницу с ТОЛЬКО кэшированными запросами.) Но все же шаблон очень прост. самая сложная часть - это вложенный цикл, который выполняется 10 раз, но если все идет хорошо, вложенный цикл не выполняется, потому что он кэшируется. (как в моем тестировании)

то есть

{% for p in posts %}
 --{{p.by.username}}
 --{{p.text}}
 {% cache 600 p p.timestamp %}
    {% for img in p.images.all %}
      --{{img.path}}
    {% endfor %}
 {% endcache %}
{% endfor %}

Я получаю ~ 80 требований / сек. Сервер для этой страницы. (Я обнаружил, что могу умножить это число на 3 в производственном развертывании) Для сравнения я получаю 1000req / s для тривиального шаблона, который содержит только короткую статическую строку.

Это известная проблема? Как мне исправить или избежать этого?

Ответы [ 2 ]

2 голосов
/ 07 ноября 2010

(Очевидно, я еще недостаточно "кармичен", чтобы оставлять комментарии, или я бы опубликовал это как комментарий, а не как ответ)

Не могли бы вы уточнить, что вы подразумеваете под "ТОЛЬКО кэшированными запросами"?

Кроме того, мне кажется, что ваша проблема может заключаться в том, что вы ударили по своей базе данных много во время рендеринга шаблона.

{% for p in posts %}
 --{{p.by.username}} {# 1 #}
 --{{p.text}}
 {% cache 600 p p.timestamp %}
    {% for img in p.images.all %} {# 2 #}
      --{{img.path}}
    {% endfor %}
 {% endcache %}
{% endfor %}

Вы предоставляете "сообщения" в свой шаблон; это один запрос, который, как вы сказали, имеет 100 результатов.

Затем для каждой итерации по сообщениям вы нажимаете на базу данных в {# 1 #}, чтобы получить p.by, который я предполагаю, что ForeignKey для auth.User.

В дополнение к этому, с неверным кэшем (первый запуск), вы снова нажимаете на db в {# 2 #}, чтобы получить список изображений этого поста.

Таким образом, для 100 элементов вы попадаете в базу данных 201 раз за запрос на начальный запуск, а 101 - с заполненным кэшем для цикла изображений.

Попробуйте использовать select_related с запросом к сообщениям, чтобы получить эти дополнительные результаты по одному запросу, если это возможно. Что-то вроде posts = Post.objects.select_related('by', 'images').filter(...) может помочь, хотя я знаю, что select_related имеет ограничения, когда дело доходит до обращения внешних ключей и полей m2m (это может не сработать для изображений, в зависимости от структуры вашей модели).

1 голос
/ 14 апреля 2018

В режиме разработки django делает много вещей, облегчающих разработку (например: перезагрузка кода; рендеринг шаблона для каждого запроса, если используется шаблон; ...).

В рабочем режиме разверните сервер WSGI, прежде чем использовать django. Такие wsgi могут быть gunicorn , uWSGI , ...

Типичная структура рабочего веб-сервера может быть такой: nginx -> gunicorn -> django

Простое сравнение (официальный учебный код django с очень простым шаблоном "Hello World! @ Time"):

{% block content %}
    <p> Hello World! @ {{ now }}</p>
{% endblock %}

Режим разработки

работать с Django напрямую

python manage.py runserver

запустить apache-ab для проверки

ab -n1000 -c10 http://127.0.0.1:8000/polls/helloworld

Server Software:        WSGIServer/0.2 # django
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /polls/helloworld
Document Length:        59 bytes

Concurrency Level:      10
Time taken for tests:   3.438 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      242000 bytes
HTML transferred:       59000 bytes
Requests per second:    290.87 [#/sec] (mean)
Time per request:       34.380 [ms] (mean)
Time per request:       3.438 [ms] (mean, across all concurrent requests)
Transfer rate:          68.74 [Kbytes/sec] received

Режим производства

беги с оружием

.. / bin / gunicorn -w4 mysite.wsgi # с 4 работниками

запустить apache-ab для проверки

ab -n1000 -c10 http://127.0.0.1:8000/polls/helloworld

Server Software:        gunicorn/19.7.1  # gunicorn
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /polls/helloworld
Document Length:        59 bytes

Concurrency Level:      10
Time taken for tests:   0.618 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      248000 bytes
HTML transferred:       59000 bytes
Requests per second:    1619.10 [#/sec] (mean)
Time per request:       6.176 [ms] (mean)
Time per request:       0.618 [ms] (mean, across all concurrent requests)
Transfer rate:          392.13 [Kbytes/sec] received
...