Профилирование долгих запросов

Данная функциональность позволяет отслеживать состояние выполнения запроса не дожидаясь его окончание. Стоит учитывать, что включение профилирования привносит некоторое количество накладных расходов для всех запросов бэкенда.

Подготовка

Для включения профилирования необходимо установить параметр query_profiling в настройках (либо в конфигурационном файле, либо динамически с помощью команды SET).

Для профилирования также необходима функционирующая очередь сообщений, в частности вызов select start_mq_broker();. Далее всё взаимодействие происходит с системными очередями, которые уже созданы.

Анализ информации очень чувствителен к статической информации поддерживаемой СУБД, поэтому рекомендуется использовать ANALYZE для исследуемых таблиц.

Анализ информации.

Для получения информации о выполнении запроса модуль предоставляет 2 основные функции:

  • qhb_running_queries
  • qhb_dump_qep

Функция qhb_running_queries возвращает временную таблицу, которая содержит следующую информацию:

Название колонкиТипОписаниеКомментарий
query_idint8Уникальный идентификатор запроса
backend_pidint8pid postgres-бэкенда, на котором выполняется запросЭквивалентен значению из pg_stat_activity.pid
query_stringtextТекстовая строка запроса
query_startedtimestamptzВремя начала работы запроса
ETCtimestamptzОриентировочное время окончания работыМожет быть NULL, при сложных запросах оценка может быть далека от реальности
elapsed_counterfloat8Внутренний счетчик для отслеживания выполненной работы запроса
estimated_total_counterfloat8Внутреннее ожидаемое количество работы для запроса

Функция qhb_dump_qep принимает идентификатор запроса из qhb_running_queries и отображает дерево плана запроса (query execution plan). Второй аргумент принимает строку со способом форматирования:

  • 'full' — отображает полные значения счетчиков;
  • 'scaled' — отображает значения счетчиков приведенные к одному порядку (отображается в поле units);
  • 'scientific' — отображает значения счетчиков;
  • 'percent' — отображает значения счетчиков в процентах;
  • 'mixed_percent' — отображает значения счетчиков в процентах и абсолютное ожидаемое значение;

Функция возвращает дерево плана, эквивалентное тому, что возвращает EXPLAIN, а также статус выполнения для каждого узла. Стоит иметь ввиду, что узлы могут иметь прогресс в 100%, но тем не менее вызываться повторно увеличивая счетчик циклов (loops). Пример анализа запроса:

# select start_mq_broker();
 start_mq_broker
-----------------

(1 row)

# create table tb (x int);
CREATE TABLE
# insert into tb select generate_series(1, 50000);
INSERT 0 50000
# select a.x, count(*) from tb a, tb b group by a.x;

В другом клиенте:

# select * from qhb_running_queries();
 query_id | backend_pid |                    query_string                    |         query_started         |              ETC              |  elapsed_counter   | estimated_total_counter
----------+-------------+----------------------------------------------------+-------------------------------+-------------------------------+--------------------+-------------------------
        7 |        1064 | select a.x, count(*) from tb a, tb b group by a.x; | 2022-02-10 16:34:01.719477+03 | 2022-02-10 16:46:49.189314+03 | 2337060.9605833497 |             97739647.85
(1 row)

# select qhb_dump_qep(query_id, 'percent') from qhb_running_queries() where query_string like 'select a.x%';
                  qhb_dump_qep
-------------------------------------------------
                                                +
 ~  Agg (progress: 0.00%, loops:  0)            +
   ~  Nest Loop (progress: 5.69%, loops:  0)    +
     -> Seq Scan (progress: 6.45%, loops:  0)   +
     ~  Material (progress: 88.30%, loops: 3648)+
       ~  Seq Scan (progress: 88.32%, loops:  0)+

(1 row)

Ограничения

Реализация в текущем виде содержит ограничения:

  • Память для внутренних структур профилирования фиксирована и ограничена 8 МиБ, при превышении данного значения, профилирование будет игнорироваться.
  • Значение ETC предсказывается интерполяцией всего по двум точкам во времени, это означает, что это значение может достаточно сильно колебаться с течением времени.
  • Для анализа работы запроса используются оценки затрат (costs) узлов дерева плана, полученные от планировщика. Данные значения могут быть неточными и они никак не корректируются в процессе выполнения запроса.