Настройка pg_stat_statements в PostgreSQL: Поиск ресурсоемких SQL-запросов
- Периодическая 100% утилизация CPU или дискового I/O кластером СУБД без явного источника нагрузки.
- Отсутствие общей статистики по среднему времени отклика (latency) и частоте вызовов SQL-запросов.
- Необходимость нормализации одинаковых по структуре параметризованных запросов.
1. Активация библиотеки в postgresql.conf
Добавьте расширение в параметр предзагрузки библиотек:
shared_preload_libraries = 'pg_stat_statements'
# Конфигурация расширения
pg_stat_statements.max = 10000
pg_stat_statements.track = all
pg_stat_statements.track_utility = off
pg_stat_statements.save = onПерезапустите PostgreSQL:
systemctl restart postgresql2. Создание расширения в целевой базе данных
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;3. Запросы для выявления проблемных SQL
Топ-10 запросов по суммарному времени выполнения (Total Execution Time):
SELECT
round((total_exec_time / 1000 / 60)::numeric, 2) AS total_minutes,
calls,
round((mean_exec_time)::numeric, 2) AS mean_ms,
round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 2) AS pct_cpu,
rows,
query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;Топ запросов по физическому чтению с диска (I/O Consumers):
SELECT
query,
calls,
shared_blks_read,
shared_blks_hit,
round((100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0))::numeric, 2) AS cache_hit_ratio
FROM pg_stat_statements
ORDER BY shared_blks_read DESC
LIMIT 10;4. Сброс накопленной статистики
SELECT pg_stat_statements_reset(); Частые вопросы (FAQ)
Почему расширение требует добавления в shared_preload_libraries?
pg_stat_statements выделяет разделяемую память (shared memory) при старте СУБД для потокобезопасного хранения хэш-таблицы нормализованных запросов между всеми воркерами.
Что означает параметр pg_stat_statements.track = top vs all?
Значение 'top' отслеживает только прямые запросы клиентов. Значение 'all' также собирает метрики вложенных запросов, вызываемых внутри хранимых процедур, функций и триггеров.
Создает ли pg_stat_statements значительные накладные расходы (overhead)?
Накладные расходы составляют менее 1-2% CPU, что делает расширение стандартом де-факто для постоянного использования на производственных серверах.
Как сбросить метрики по конкретному запросу (queryid)?
В PostgreSQL 12+ доступна функция pg_stat_statements_reset(userid, dbid, queryid), позволяющая точечно очистить статистику единичного запроса.