N+1 возникает, когда для списка объектов система отдельно догружает связанные данные для каждого элемента. В GraphQL это особенно заметно: один красивый запрос с фронтенда может порождать сотни SQL-запросов внутри backend.
Когда это становится проблемой
Страница открывается медленно, база нагружается, API падает под небольшой нагрузкой. Добавление серверов не решает проблему, потому что корень находится в логике выборки данных.
Что проверяю в первую очередь
- Количество SQL-запросов на один HTTP/GraphQL-запрос
- Resolvers, которые ходят в базу для каждого элемента списка
- Отсутствие dataloader или eager loading
- Повторные запросы одинаковых сущностей
- Профилирование времени базы и приложения
Как исправляю
Я нахожу конкретные resolver или участки ORM, которые создают лавину запросов. Затем объединяю выборки, добавляю dataloader, правильные join или предварительную загрузку.
- Внедряю DataLoader или аналогичное батчирование
- Исправляю ORM-запросы и eager loading
- Добавляю кеш для повторяющихся справочников
- Ограничиваю глубину и объем GraphQL-запросов, если это нужно
Что важно не сломать
Нельзя просто кешировать все подряд. Нужно понимать, какие данные можно кешировать, а какие должны оставаться актуальными.
Что будет после исправления
- Количество запросов к базе резко уменьшается
- Страница открывается быстрее
- API выдерживает больше одновременных пользователей
- Появляются метрики для контроля N+1 в будущем
Что подготовить перед обращением
- Пример медленной страницы или GraphQL-запроса
- Доступ к backend-коду
- Логи SQL или профайлер
- Описание базы и ORM
Вопросы и ответы
Можно ли исправить без полной переделки?
Да, обычно это точечная оптимизация resolvers и запросов. Архитектуру полностью менять не нужно.
Сколько времени занимает диагностика?
Первый N+1 обычно находится быстро через профайлер. Исправление зависит от количества связей и тестов.
Нужна похожая задача?
Напишите в Telegram @rabotator_support и коротко опишите проблему. Я посмотрю симптомы, предложу понятный план работ и скажу, какие доступы нужны для безопасного исправления.