Типичный сценарий: ваше приложение прекрасно работает с тестовыми наборами из сотни записей, но начинает захлебываться при реальной нагрузке. Задержки в 3-5 секунд на критических операциях, таймауты соединений с базой данных, потребление памяти, растущее как на дрожжах – эти симптомы знакомы многим разработчикам. Корень проблемы часто лежит в цепочке микрооптимизаций, пропущенных на этапе проектирования.
Ошибка 1: Наивные запросы к БД
Рассмотрим классический пример генерации отчета о пользовательской активности:
# Плохая практика
activities = []
for user in User.objects.all():
activities.extend(user.activities.all())
Этот код порождает N+1 проблему: 1 запрос на получение пользователей + N отдельных запросов для активности каждого пользователя. При 10 000 пользователей получаем 10 001 запросов. Исправление:
# Решение: жадная загрузка
activities = Activity.objects.select_related('user').all()