Как диагностировать проблему скорости рендеринга django?

Я пытался выяснить, что замедляет мои запросы, и все, что мне удалось выяснить, это то, что происходит замедление рендеринга ответа.

Я провел несколько тестов запроса, сериализатора и рендеринга JSON следующим образом:

client = Client.objects.get(user__username="pugdog")
start = parse("2021-09-01T00:00:00-04:00")
end = parse("2021-10-01T00:00:00-04:00")
db_test_start_time = time()
events = Event.objects.filter(client=client, start__gt=start, end__lt=end)
list(events)
db_test_end_time = time()

factory = APIRequestFactory()
request = factory.get('/')
serializer_context = {'request': Request(request), }
output = []
for event in events:
    serializer = EventReadSerializer(instance=event, context=serializer_context)
    output.append(serializer.data)
renderer = JSONRenderer()
json_output = renderer.render(output)
serializer_test_end_time = time()
print(f"query speed: {db_test_end_time - db_test_start_time}")
print(f"serializer speed: {serializer_test_end_time - db_test_end_time}")
print(f"Total time: {serializer_test_end_time - db_test_start_time}")

Вывод:

query speed: 0.006450176239013672
serializer speed: 2.926229238510132
Total time: 2.9326794147491455

Это время, необходимое для обработки запроса и преобразования его в JSON, но когда я пытаюсь получить эти данные с помощью REST-клиента API "Insomnia", это занимает около 43,8 секунды, что означает, что у меня где-то сильно замедляется работа. Я запускаю Insomnia на той же машине, на которой веду разработку, поэтому проблем с сетью быть не должно.

Этот тест проводится, когда я заполняю базу данных 100 объектами Event. Я решил провести тесты с разным количеством объектов, чтобы посмотреть, является ли зависимость между количеством данных и временем ответа линейной, что может помочь в выяснении проблемы, например, если есть какая-то проблема с моей авторизацией/аутентификацией, и она не имеет отношения к конкретному запросу. Когда я делаю 20 событий, время, необходимое для получения ответа в Insomnia, составляет около 9 секунд, в то время как в приведенном выше тесте - около 0,6 секунды. Это почти линейная зависимость от скорости по обоим показателям.

Большая часть моего API достаточно отзывчива, но эта конкретная часть работает крайне медленно. Что еще можно проверить, чтобы выяснить, что именно замедляет работу?

Ваш сериализатор сериализует не только данные из instance, но и из связанных объектов. Это означает, что сериализатор будет делать запросы к связанным моделям.

Мы можем увеличить производительность, используя .select_related(…) [Django-doc] и .prefetch_related(…) [Django-doc]:

events = Event.objects.filter(
    client=client, start__gt=start, end__lt=end
).prefetch_related(
    'resources', 'rrule'
).select_related('customer', 'customer__user')

вероятно, Customer также делает запросы для поиска custom_data и notes. Если вы совместно используете соответствующую модель Customer и сериализатор SimplifiedCustomerSerializer, мы, вероятно, сможем уменьшить количество запросов и для этих элементов.

Вернуться на верх