После перехода с MS SQL Server на PostgreSQL запрос 1С может закончиться, а технологический журнал — продолжить фиксировать SELECT FASTTRUNCATE. План выглядит нормальным, но пользователь всё равно ждёт.

В разборе «Тантор Лабс» FASTTRUNCATE занял 12,9% процессорного времени в базе 1С:ERP объёмом 700 ГБ. В другом сценарии операции с контролируемыми сделками после миграции замедлились на 70%. Основное время уходило именно на FASTTRUNCATE.

Но одной строки в журнале мало. Свяжите вызов с запросом 1С, временной таблицей и предыдущими командами PostgreSQL. Тогда станет ясно, что менять: запрос, версию платформы или настройки СУБД.

За одним оператором ПОМЕСТИТЬ скрываются семь операций

В запросе 1С разработчик видит один оператор — ПОМЕСТИТЬ. На стороне PostgreSQL за ним стоит цепочка из семи служебных операций.

Материал «Тантор Лабс» о временных таблицах приводит такой порядок:

DROP TABLE IF EXISTS pg_temp.<имя_таблицы>;

CREATE TEMPORARY TABLE pg_temp.<имя_таблицы> (...);

CREATE INDEX... ON pg_temp.<имя_таблицы> (...);

INSERT INTO pg_temp.<имя_таблицы> (...)
SELECT...;

ANALYZE pg_temp.<имя_таблицы>;

DROP INDEX...;

SELECT FASTTRUNCATE('pg_temp.<имя_таблицы>')
ON CONFLICT DO NOTHING;

Имена объектов меняются вместе с запросом и соединением. Для диагностики важнее порядок: задержка способна возникнуть на любом из семи этапов.

Операция платформыЗачем она нужнаГде искать затрату
DROP TABLE IF EXISTSУбирает одноимённый объект перед первым созданиемБлокировки и обращения к системному каталогу
CREATE TEMPORARY TABLEСоздаёт таблицу в схеме pg_tempИзменения pg_class, pg_attribute, pg_depend, pg_type
CREATE INDEXГотовит индекс до загрузки строкПостроение индекса и его поддержка при вставке
INSERTЗаписывает результат исходной выборкиПлан запроса, чтение постоянных таблиц, объём результата
ANALYZEОбновляет статистику временной таблицыВремя анализа и точность собранной статистики
DROP INDEXУдаляет служебный индексОперации с relation и системным каталогом
SELECT FASTTRUNCATEОчищает таблицу перед повторным использованиемУсечение таблицы и состояние её статистики

Вывод: не списывайте всю задержку на ПОМЕСТИТЬ. Сначала найдите операцию, которая забрала время.

План исходной выборки описывает лишь часть работы. Если INSERT уже завершился, задержку ищите в ANALYZE или FASTTRUNCATE. Когда исходный запрос содержит WITH, отдельно проверьте работу CTE внутри планов PostgreSQL.

Почему временная таблица остаётся после запроса

Платформа не удаляет временную таблицу после каждого обращения. Вместо этого она может очистить объект и позже заполнить его новыми данными.

Сервер 1С хранит имя базы, состав колонок, номер соединения и имя временной таблицы. С этими сведениями работает функция lookupTmpTable на стороне сервера 1С.

При следующем выполнении платформа сравнивает структуру полей. Если соединение осталось тем же, а структура совпала, 1С использует готовую таблицу повторно. PostgreSQL удалит её, когда закроется соединение.

Так платформа реже создаёт объекты заново. Очистка при этом остаётся самостоятельной операцией, поэтому технологический журнал показывает отдельный вызов.

Оператор УНИЧТОЖИТЬ тоже вызывает FASTTRUNCATE. Такой же вызов происходит при закрытии МенеджераВременныхТаблиц или после прекращения его существования.

Внутри FASTTRUNCATE функция heap_truncate удаляет строки. Затем платформа может записать в ту же таблицу другой набор данных.

FASTTRUNCATE нельзя откатить вместе с транзакцией

FASTTRUNCATE работает не так, как обычная транзакционная команда. Это нужно учитывать и при изменениях, и при диагностике.

Документация Postgres Pro Enterprise 17 описывает модуль fasttrun для поддержки 1С. Он очищает временные таблицы без увеличения pg_class.

Операция не поддерживает транзакционный откат. Результат виден сразу, причём уровень изоляции на это не влияет.

Открытая транзакция не делает эксперимент обратимым. Проверяйте изменения на отдельном контуре и заранее готовьте путь возврата к исходному состоянию.

Пустая таблица тоже может попасть под очистку

Временная таблица могла не получить ни одной строки, но платформа всё равно вызовет FASTTRUNCATE. Для диагностики это один из самых показательных сценариев.

В разборе «Тантор Лабс» основную часть времени функция тратила внутри heap_truncate. Пропуск FASTTRUNCATE для заведомо пустой таблицы снял эту затрату.

Переносить такую правку на любую базу нельзя. Сначала подтвердите, что в проблемной ветке таблица остаётся пустой.

Проверьте условие, которое собирает набор для ПОМЕСТИТЬ. Запрос может создавать таблицу заранее, хотя следующая ветка к ней не обращается. В таком случае лучше вообще не создавать объект.

Проверка после заполнения опоздает. К этому моменту платформа уже могла выполнить CREATE TABLE, построить индекс и запустить ANALYZE. Деньги на эти операции уже потрачены.

Долгий FASTTRUNCATE и рост каталогов — разные проблемы

Каждое создание временной таблицы меняет системный каталог PostgreSQL. При частых созданиях и удалениях в таблицах каталога накапливаются версии строк.

В статье «Тантор Лабс» о временных таблицах PostgreSQL указано до 13 затрагиваемых таблиц. Быстрее других растут pg_attribute, pg_class, pg_depend и pg_type.

Но размер каталогов сам по себе не доказывает, что FASTTRUNCATE работает долго. Авторы материала пишут, что рост обычно не мешает создавать и удалять relations.

Сложности начинаются, когда PostgreSQL не может удалить старые версии строк. Удерживаемый горизонт базы не даёт автовакууму закончить очистку.

Здесь два разных симптома. Первый: отдельный вызов FASTTRUNCATE занимает время. Второй: системные каталоги растут и долго обслуживаются. Проверять их нужно по-разному.

Наблюдаемый признакВозможная причинаЧто проверитьСледующий шаг
FASTTRUNCATE дольше соседних операцийВремя уходит внутри очистки таблицыДлительность INSERT, ANALYZE и FASTTRUNCATE для одного запросаСопоставить вызов с размером и заполнением временной таблицы
FASTTRUNCATE вызван после пустого набораТаблица создана в ветке без данныхУсловия до ПОМЕСТИТЬ и число полученных строкНе создавать таблицу в этой ветке
Растут таблицы системного каталогаЧастое создание временных объектовРазмеры pg_attribute, pg_class, pg_depend, pg_typeПроверить автовакуум и удерживаемый горизонт
После ДОБАВИТЬ меняется планСтатистика не пересчитанаПорядок ДОБАВИТЬ, ANALYZE и последующей выборкиПроверить online_analyze на тестовом контуре
Проблема появилась после миграцииСравниваются разные механизмы СУБДОдин сценарий, входные данные и цепочка SQLСравнивать этапы, а не общее время операции

Вывод: FASTTRUNCATE в журнале указывает, куда смотреть. Готового диагноза эта строка не даёт.

Что искать в технологическом журнале

На первом проходе отберите события Sql по маске %FASTTRUNCATE%. Такой фильтр приведён в материале Инфостарта «Временные таблицы и SELECT FASTTRUNCATE».

Перечень вызовов покажет частоту, но не причину задержки. Возьмите один медленный экземпляр и восстановите предшествующие события:

  1. Найдите исходный запрос 1С и его контекст.
  2. Определите имя временной таблицы в pg_temp.
  3. Сопоставьте CREATE, INSERT, ANALYZE и FASTTRUNCATE.
  4. Проверьте, появились ли строки после INSERT.
  5. Сравните длительность этапов для быстрых и медленных выполнений.

Берите один прикладной сценарий и одинаковые входные данные. Иначе результаты исказят объём выборки, состояние кэша или параллельная нагрузка.

Если тормозит INSERT, FASTTRUNCATE лишь стоит в конце дорогого запроса. Проверяйте план исходной выборки, индексы постоянных таблиц и оценку числа строк.

Если задерживается сам FASTTRUNCATE, выясните, сколько данных попало во временную таблицу. Для пустого объекта и большой выборки нужны разные изменения.

Если время забирает ANALYZE, проверяйте статистику и порядок заполнения. Настройка системных каталогов эту операцию не ускорит.

Что поменялось в платформе 1С 8.3.25

В 1С 8.3.25 доработали механизм временных таблиц. Изменения затронули несколько индексов и online_analyze.

Один номер версии не гарантирует, что задержка исчезнет. В доступных материалах нет общего замера для разных конфигураций и пользовательских баз.

Отдельно проверьте оператор ДОБАВИТЬ. По разбору «Тантор Лабс», после него платформа не пересчитывает статистику временной таблицы на стороне СУБД.

Следующая выборка может получить оценки по старому числу строк. online_analyze закрывает именно этот разрыв: обновляет статистику после изменения данных.

Испытывайте настройку только при совпадении признаков. Найдите ДОБАВИТЬ, подтвердите изменение числа строк, затем проверьте ошибку оценки в плане.

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

Параметры временных таблиц зависят от сборки PostgreSQL

Сборки PostgreSQL различаются набором параметров и их реализацией. Совпадающее имя настройки ещё не говорит об одинаковом поведении.

По материалу «Тантор Лабс», в Tantor Postgres 17.5 добавили enable_temp_memory_catalog и enable_delayed_temp_file. Первый параметр меняет работу с метаданными временных таблиц, второй — с их файлами.

enable_temp_memory_catalog включается для отдельной сессии без перезапуска экземпляра. Так можно ограничить эксперимент одним соединением, а уже потом решать вопрос с общей конфигурацией.

Сборка PostgreSQL 16 от 1С ИТС тоже содержит enable_temp_memory_catalog. Но внутри она устроена иначе, чем реализация Tantor Postgres 17. Параметра enable_delayed_temp_file в этой сборке нет.

СборкаДоступная настройкаЧто меняетКак проверять
Tantor Postgres 17.5enable_temp_memory_catalogУбирает изменения системного каталога при работе с временными таблицамиВключить для тестовой сессии и сравнить обращения к каталогам
Tantor Postgres 17.5enable_delayed_temp_fileМеняет работу с файлами временных таблицПроверить на том же запросе и наборе данных
PostgreSQL 16 от 1С ИТСenable_temp_memory_catalogКэширует метаданные по собственной реализации сборкиСвериться с документацией именно этой поставки
PostgreSQL 16 от 1С ИТСenable_delayed_temp_file отсутствуетПеренести настройку из Tantor нельзяНе добавлять неизвестный параметр в конфигурацию

Вывод: не переносите параметры между сборками только из-за похожих названий. Сверяйте поставщика, редакцию, версию и документацию.

Если вы ещё выбираете СУБД, одной проблемной функцией сравнение не ограничивается. Лицензирование, сопровождение и отказоустойчивость обеих платформ разобраны в материале о SQL Server и PostgreSQL для 1С.

Порядок проверки без слепой смены СУБД

Возьмите один медленный вызов. Найдите FASTTRUNCATE в технологическом журнале и соберите связанную с ним цепочку SQL.

Дальнейшее действие зависит от обнаруженного признака:

После правки повторите тот же сценарий с прежними входными данными. Сопоставьте длительность каждой операции и проверьте прикладной результат в 1С.

Обновление платформы, настройка PostgreSQL и изменение запроса устраняют разные причины. Если журналы не разделяют их, закажите диагностику контура по фактической цепочке запросов.

Правило для работы: сначала привяжите FASTTRUNCATE к конкретной временной таблице. Потом найдите дорогую операцию. И лишь затем меняйте запрос, платформу или СУБД.

fasttruncate postgresql временные таблицы оптимизация 1с технологический журнал