Кажется, что нет общего поддерживаемого метода, но есть некоторые приемы, которые могут использоваться в ограниченных контекстах для оценки хода выполнения отдельного запроса. Вот некоторые из них.
Последовательности
Если запрос SELECT или UPDATE включает в себя любой из них nextval(sequence_name), или INSERT имеет целевой столбец со значением nextvalпо умолчанию, текущее значение последовательности может быть повторно запрошено в другом сеансе SELECT sequence_name.last_value. Это работает, потому что последовательности не ограничены транзакциями. Когда план выполнения таков, что последовательность увеличивается линейно во время запроса, он может использоваться как индикатор прогресса.
pgstattuple
Pgstattuple модуль вно обеспечивает функции , которые могут PEEK непосредственно на страницах данных. Похоже, что когда кортежи вставляются в пустую таблицу и еще не зафиксированы, они учитываются в dead_tuple_countполе из pgstattupleфункции.
Демо с 9.1: создать пустую таблицу
CREATE TABLE tt AS (n numeric);
Давайте вставим 10M строк в него:
INSERT INTO tt SELECT * FROM random() from generate_series(1,10000000);
В другом сеансе проверяйте pgstattuple каждую секунду во время вставки:
$ while true;
do psql -Atc "select dead_tuple_count from pgstattuple('tt')";
sleep 1;
done
Полученные результаты:
0
69005
520035
1013430
1492210
1990415
2224625
2772040
3314460
3928660
4317345
4743770
5379430
6080950
6522915
7190395
7953705
8747725
9242045
0
Когда вставка завершена, она возвращается к 0 (все кортежи становятся видимыми и активными).
Этот прием также может быть использован, когда таблица не была заново создана, но инициал dead_tuple_count, вероятно, будет иметь ненулевое значение, и он также может измениться одновременно, если происходит другая операция записи, такая как autovacuum (предположительно? Не уверен, какой уровень параллелизма ожидать с автовакуумом).
Однако его нельзя использовать, если таблица создается самим оператором ( CREATE TABLE ... AS SELECTили SELECT * INTO newtable), поскольку создание выполняется. Обходной путь должен был бы создать таблицу без строк (добавить LIMIT 0) и заполнить ее в следующей транзакции.
Обратите внимание, что pgstattupleэто не бесплатно: он сканирует всю таблицу при каждом вызове. Также это ограничено суперпользователями.
Пользовательский счетчик
В блоге Павла Стегуле он предоставляет функцию счетчика, реализованную в C, которая вызывает NOTICEs при указанном количестве выполнений. Вы должны как-то объединить функцию с запросом, чтобы исполнитель вызвал ее. Уведомления отправляются во время запроса, и им не нужен отдельный сеанс, только клиент SQL, который их отображает ( psqlчто является очевидным кандидатом).
Пример INSERT INTO переработан для получения уведомлений:
/* transformation */
INSERT INTO destination_table
SELECT (r).*
FROM (SELECT counter(to_destination_table(_source), 1000, true) r
FROM source _source) x
Связанный вопрос по stackoverflow, для функций:
Как сообщить о прогрессе от продолжительной функции PostgreSQL клиенту
Будущие варианты?
По состоянию на май 2017 года сообщество разработчиков представило многообещающий патч:
[PATCH v2] Команда Progress для отслеживания хода выполнения длительных SQL-запросов.
который может закончиться как общее решение в PostgreSQL 11 или более поздней версии. Пользователи, которые хотят участвовать в незавершенных функциях, могут применить последнюю версию исправления и попробовать предложенную PROGRESSкоманду.
pvкоманду раньше, и она не была установлена на моем сервере Debian по умолчанию, но она находится в репозитории. В описании говорится, что «pv (Pipe Viewer) может быть вставлен в любой нормальный конвейер между двумя процессами, чтобы наглядно показать, как быстро проходят данные». Очень полезная команда!