🎙
Кажется, что база данных тормозит: 7 мест, где искать проблемуОтвет сервиса занимал 100 мс, а теперь приходит через несколько секунд. Первая мысль: базе не хватает ресурсов. Но увеличение CPU и памяти помогает не всегда. Причина может быть в запросе, индексе, блокировке или даже за пределами базы данных.
Разберём, что проверить в первую очередь.
1️⃣
А проблема точно в базе?Пользователь ждал ответа пять секунд, а SQL выполнялся 70 мс. Остальное время могло уйти на сеть, бизнес-логику, внешний API или ожидание свободного соединения.
Поэтому сначала сравните общее время ответа со временем выполнения запросов к БД.
2️⃣
Не хватает подходящего индексаSELECT *
FROM orders
WHERE user_id = 14253;
Без подходящего индекса СУБД может просматривать значительную часть таблицы. Но сам по себе индекс не гарантирует ускорения: всё зависит от размера таблицы, распределения данных и условий запроса.
Создавать индексы на каждый столбец тоже не стоит. Они занимают место и добавляют работу при INSERT, UPDATE и DELETE.
3️⃣
Запрос обрабатывает слишком много данныхJOIN, ORDER BY, GROUP BY и агрегатные функции сами по себе не являются проблемой. Сложности начинаются, когда запрос читает слишком много строк, выполняет повторные сканирования или переносит сортировку и агрегацию на диск.
Посмотреть план выполнения поможет:
EXPLAIN
SELECT ...;
Чтобы увидеть фактическое время и количество строк, можно использовать EXPLAIN ANALYZE. Но важно помнить: он действительно выполняет запрос.
4️⃣
Приложение попало в N+1Сначала приложение получает 100 пользователей, а затем отдельно запрашивает заказы для каждого из них. В результате вместо одного или двух запросов база получает 101.
На больших объёмах это увеличивает нагрузку и время ответа. Возможные решения: JOIN, пакетные запросы или предусмотренная ORM предварительная загрузка данных.
5️⃣
Запросы ждут друг другаОдна транзакция удерживает блокировку, а другие запросы ожидают её освобождения. Особенно опасны долгие транзакции, которые удерживают конфликтующие блокировки.
Проверяйте заблокированные запросы, время ожидания и длительность открытых транзакций.
6️⃣
Закончились свободные соединенияЕсли пул соединений полностью занят, приложение ждёт свободное соединение и ещё не отправляет SQL в базу. Сам запрос может выполняться за миллисекунды, но пользователь всё равно получает ответ с задержкой.
Проверьте размер пула, количество активных соединений, длительность их использования и время ожидания.
7️⃣
Изменились объём данных или план выполненияЗапрос, который быстро работал на 100 тысячах строк, может замедлиться на 100 миллионах. Кроме самого объёма данных, на производительность влияют распределение значений, актуальность статистики и выбранный план выполнения.
Могут понадобиться пересмотр индексов, оптимизация запроса, обновление статистики, архивирование или партиционирование. Но сначала нужно подтвердить причину измерениями.
🔎
С чего начать диагностику?Метрики всей цепочки → статистика и логи медленных запросов → ожидания и блокировки → пул соединений → CPU, RAM и I/O → план конкретного SQL-запроса.
Не начинайте сразу с решения: «добавим индекс», «перепишем запрос» или «дадим больше памяти». Медленная работа системы — это симптом. Задача инженера сначала поставить диагноз.