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

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



Подготовка

Для включения профилирования необходимо установить параметр 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 и отображает дерево плана запроса. Второй аргумент принимает строку со способом форматирования:

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

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

# 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 предсказывается интерполяцией всего по двум точкам во времени, что означает, что это значение может достаточно сильно колебаться с течением времени.
  • Для анализа работы запроса используются оценки затрат узлов дерева плана, полученные от планировщика. Данные значения могут быть неточными, и они никак не корректируются в процессе выполнения запроса.