pg_stat_statements отслеживает форму запросов, количество вызовов и время выполнения по всей базе. Это самый короткий путь от «база почему-то тормозит» до «вот эти пять запросов съедают большую часть времени».Включаем
pg_stat_statementsЕсли вы используете Crunchy Bridge, расширение уже доступно по умолчанию и можно сразу переходить к
CREATE EXTENSION.При самостоятельном размещении нужно изменить
postgresql.conf и перезапустить PostgreSQLshared_preload_libraries = 'pg_stat_statements, ...'
pg_stat_statements.track = top
Можно указать
top или all. Режим all также учитывает запросы внутри функций и процедур. top используется по умолчанию и отслеживает только запросы, выполняемые клиентами.Затем включаем расширение для нужной базы
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
Ищем дорогие запросы
Для такой проверки обычно полезнее смотреть на суммарное время выполнения. Запрос средней тяжести, который вызывается миллионы раз, часто наносит больше вреда, чем один редкий медленный запрос.
SELECT
round(total_exec_time::numeric, 1) AS total_ms,
calls,
round(mean_exec_time::numeric, 2) AS mean_ms,
rows,
query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;
Также стоит смотреть на среднее время и количество строк. Например, последовательное сканирование может проявиться как большое
total_exec_time и большое значение rows у запроса, который в норме должен находить одну конкретную запись.Что означают столбцы
•
calls — сколько раз запрос выполнялся с момента последнего сброса статистики•
total_exec_time и mean_exec_time — суммарное и среднее время выполнения в миллисекундах•
rows — общее количество полученных или изменённых строк•
query — нормализованный запрос с параметрами вида $1Статистика копится до ручного сброса
SELECT pg_stat_statements_reset();
Важно помнить, что сброс удаляет всю накопленную историю. Для анализа можно либо сбросить статистику перед заранее известным периодом высокой нагрузки, либо сравнивать текущие данные с сохранённым ранее снимком.
Что делать с найденными запросами
1. Запустить
EXPLAIN с реальными параметрами. pg_stat_statements показывает форму запроса, но не план выполнения.2. Проверить недостающие индексы, сбросы на диск из-за
work_mem и слишком большое количество мелких запросов приложения вроде N+1.3. После деплоя или добавления индекса сбросить статистику, дать системе поработать под реальной нагрузкой и проверить, уменьшилось ли суммарное время выполнения.

