Как диагностировать причину задержек в базе данных при низкой нагрузке?

«Как диагностировать причину задержек в базе данных при низкой нагрузке?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Задержки при низкой нагрузке часто указывают на проблемы с конкретными запросами, блокировками или конфигурацией.

Пошаговая диагностика:

  1. Анализ медленных запросов:

    • PostgreSQL: EXPLAIN ANALYZE <ваш_запрос> для анализа плана выполнения.
    • MySQL: Активируйте и проверьте slow query log.
  2. Проверка блокировок (deadlocks, long-running transactions):

    -- PostgreSQL: активные блокировки
    SELECT pid, relation::regclass, mode, granted FROM pg_locks WHERE NOT granted;
    -- Долгие транзакции
    SELECT * FROM pg_stat_activity WHERE state = 'active' AND now() - state_change > interval '5 minutes';
  3. Проверка использования индексов: Убедитесь, что запросы используют эффективные индексы, а не выполняют полное сканирование таблиц (sequential scan).

  4. Мониторинг ресурсов сервера:

    • Дисковая подсистема: Высокий await времени отклика диска (команда iostat).
    • Память: Нехватка оперативной памяти, ведущая к своппингу.
    • CPU: Постоянная высокая загрузка одним процессом.
  5. Проверка сетевой задержки: Измерьте ping и traceroute между сервером приложения и БД.

  6. Анализ конфигурации пула соединений: Неправильные настройки (максимум/минимум соединений, таймауты) в приложении (HikariCP, Tomcat JDBC) могут вызывать задержки.

Типичные причины: отсутствующие индексы, блокировки из-за неоптимальных транзакций, проблемы с диском I/O, неверные настройки БД.