Как находить и анализировать медленные запросы в PostgreSQL?

Ответ

Для отслеживания и анализа медленных запросов в PostgreSQL существуют несколько основных подходов:

  1. Логирование медленных запросов (log_min_duration_statement)

    • Что это: Простой способ логировать все запросы, выполнение которых превышает указанный лимит.
    • Как использовать: В файле postgresql.conf установите параметр:
      # Логировать запросы, выполняющиеся дольше 500 миллисекунд
      log_min_duration_statement = 500
    • Плюсы: Легко настроить. Помогает ловить неожиданно медленные запросы.
  2. Модуль pg_stat_statements

    • Что это: Мощное расширение, которое собирает агрегированную статистику по всем выполненным запросам.
    • Как использовать:
      
      -- Включить расширение (один раз на базу данных)
      CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

    -- Найти топ-10 запросов по общему времени выполнения SELECT (total_exec_time / 1000 / 60) as total_minutes, calls, mean_exec_time, query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;

    
    *   **Плюсы:** Идеально для поиска самых "дорогих" запросов в системе в целом.
  3. Анализ плана выполнения (EXPLAIN ANALYZE)

    • Что это: Инструмент для детального анализа плана выполнения конкретного запроса. Показывает реальное время выполнения каждого шага.
    • Как использовать:
      EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM users WHERE email = 'test@example.com';
    • Плюсы: Дает исчерпывающую информацию для оптимизации одного запроса (поиск узких мест, оценка использования индексов).
  4. Мониторинг в реальном времени (pg_stat_activity)

    • Что это: Системное представление, показывающее текущую активность всех подключений.
    • Как использовать:
      -- Найти запросы, которые выполняются прямо сейчас дольше 5 секунд
      SELECT pid, now() - query_start AS duration, query
      FROM pg_stat_activity
      WHERE state = 'active' AND (now() - query_start) > interval '5 seconds'
      ORDER BY duration DESC;
    • Плюсы: Помогает диагностировать проблемы "в моменте", например, зависшие транзакции или долгие запросы, блокирующие другие.