Содержание
Коротко
Если приложение тормозит, виновата чаще всего база данных, а не фреймворк или CDN. На Dev.to инженер с девятилетним опытом собрал шесть стратегий, которые на реальных проектах сокращали время запросов до 60%.
Что произошло
Автор начинает с тезиса: «никогда не оптимизируй запрос, который не профилировал». Первый шаг — slow query log (порог ~200 мс в PostgreSQL и MySQL) и еженедельный разбор логов. Второй — EXPLAIN ANALYZE: не план на бумаге, а реальное время выполнения.
Пример из продакшена: поиск вакансий сканировал 200k строк последовательным обходом таблицы, фильтровал 187k и тратил 1,8 с. Составной индекс (status, created_at DESC) снизил время до 12 мс — минус 99,3%. Дальше — частичные индексы (только status = 'active', ~85% меньше размер), покрывающий индекс с INCLUDE для index-only scan без обращения к heap.
Отдельный блок — ошибки ORM: N+1 (150 запросов на страницу → 8 после жадной подгрузки), коррелированные подзапросы вместо JOIN, аналитика через оконные функции вместо пяти обращений к серверу из приложения. Для read-heavy нагрузок — материализованные представления (обновление по cron), стратегическая денормализация (JSONB-кэш статистики на строке организации).
На уровне инфраструктуры: PgBouncer (500 клиентских соединений на 25 backend), read replicas для поиска и отчётов, Redis с TTL и инвалидацией по событиям (vacancy:created).
Почему это важно
Full-stack команды часто оптимизируют React и забывают, что p95 API упирается в один тяжёлый SELECT. Индекс «на всякий случай» может замедлить запись; без EXPLAIN вы не увидите разницу. Материализованные view и кэш — не «антипаттерн», а инструмент, когда свежесть данных можно измерить в минутах, а не миллисекундах.
На практике
- Включите slow query log; раз в неделю берите топ-20 самых медленных запросов.
- На каждый — EXPLAIN ANALYZE; ищите seq scan на таблицах >10k строк и sort без индекса.
- Составные индексы: порядок колонок = порядок фильтра и сортировки в запросе.
- Проверьте ORM: N+1,
withCount, замена подзапросов на JOIN/CTE. - Дашборды с преобладанием чтения — материализованное представление + периодический
REFRESH CONCURRENTLY. - Пул (PgBouncer) и реплики — до того, как «лечить» кэшем то, что можно ускорить SQL.
Итог
Оптимизация БД — дисциплина, а не разовый спринт. Шесть стратегий из статьи (профилирование → индексы → SQL → схема → соединения → кэш) дают измеримый эффект; гайд на Dev.to полезен как чеклист перед очередным «ускорим фронт».