Зміст
Коротко
Якщо застосунок гальмує, винна частіше за все база даних, а не фреймворк чи 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 корисний як чеклист перед черговим «прискоримо фронт».