Многие технические специалисты при переходе с MS SQL Server на PostgreSQL сталкиваются с неприятным сюрпризом: производительность системы на свободной СУБД оказывается значительно ниже, иногда в десятки раз. Особенно это заметно при массовой записи документов в конфигурациях типа "Зарплата и управление персоналом" (ЗУП). Разберем по шагам, почему так происходит, как диагностировать узкие места и что нужно сделать, чтобы PostgreSQL работал быстрее, чем коммерческие аналоги.
Рассмотрим типичный сценарий: при записи документа БольничныйЛист со включенным флагом ОбменДанными.Загрузка = Истина скорость в MS SQL составляет около 26 документов в секунду, а в PostgreSQL — всего 1.5 документа. На первый взгляд кажется, что проблема в самой СУБД, однако в 99% случаев причина кроется в отсутствии оптимизированных индексов или некорректных планах запросов.
Выясним причину такого поведения. Для этого нам необходимо заглянуть "под капот" СУБД и увидеть, какие именно запросы выполняются в момент записи документа. В 1С метод Записать() инициирует не только вставку данных, но и предварительное чтение объекта, проверку табличных частей и системных полей.
Чтобы понять, где именно PostgreSQL "спотыкается", воспользуемся модулем auto_explain. Он позволяет выводить планы выполнения медленных запросов прямо в лог-файл СУБД. Проанализируем настройки, которые необходимо внести в файл postgresql.conf:
shared_preload_libraries = 'auto_explain'
auto_explain.log_min_duration = '0'
auto_explain.log_analyze = true
auto_explain.log_buffers = true
auto_explain.log_timing = true
Важный нюанс: Установка параметра auto_explain.log_min_duration = '0' заставит систему логировать абсолютно все запросы. Это создаст большую нагрузку, поэтому используйте эту настройку только на время теста. После настройки мы увидим, что при выполнении метода ПолучитьОбъект платформа 1С формирует десятки запросов к основной таблице документа и ко всем его табличным частям.
Проанализируем фрагмент лога, полученного после записи документа. В проблемных случаях мы увидим примерно следующую картину:
Query Text: SELECT T2._LineNo1046, T2._Fld1047RRef ... FROM _Document304_VT1045 T2 ...
...
-> Seq Scan on _document304_vt1045 t2 (cost=0.00..2837.60 rows=2 width=420)
Filter: ((_fld815 = '0'::numeric) AND (_document304_idrref = '\\x8721...'::bytea))
Rows Removed by Filter: 37882
Buffers: shared read=2383
Посмотрим внимательнее на строку Seq Scan. Это означает Sequential Scan — последовательное сканирование всей таблицы. PostgreSQL физически читает все 37 882 строки из таблицы табличной части документа, чтобы найти всего одну нужную запись. Это происходит потому, что у СУБД нет подходящего индекса по полям разделителя (_fld815) и ссылки (_document304_idrref).
В MS SQL такие индексы часто создаются автоматически или поддерживаются более агрессивно, а в PostgreSQL при определенных манипуляциях с базой (например, некорректном переносе данных) они могут отсутствовать или быть повреждены.
Самый простой и эффективный способ восстановить индексы в соответствии с логикой платформы 1С — это процедура реструктуризации. Не стоит пытаться создавать индексы вручную через SQL-запросы, так как платформа 1С должна "знать" об их существовании.
Выполним следующие действия:
После этой операции PostgreSQL создаст все необходимые индексы, включая те, что имитируют кластерные индексы MS SQL. Как показывает практика, после реструктуризации скорость записи может вырасти с 1.5 до 40 документов в секунду, что даже превосходит показатели MS SQL в некоторых тестах.
Если реструктуризация помогла, но вы хотите выжать из системы максимум, проанализируем дополнительные параметры оптимизации PostgreSQL для Linux-систем (Ubuntu, Astra Linux):
synchronous_commit = off в конфиге. Это даст колоссальный прирост на операциях записи.random_page_cost = 1.1. Это заставит планировщик чаще использовать индексы (Index Scan), а не переходить на Seq Scan.
autovacuum_vacuum_scale_factor = 0.01
autovacuum_analyze_scale_factor = 0.005
Рассмотрим, нужно ли делать реструктуризацию постоянно. Нет, это разовая акция для исправления структуры. Однако для поддержания высокой скорости работы необходимо регулярно выполнять регламентные операции средствами самой СУБД:
Таким образом, мы выяснили, что PostgreSQL не является "медленным" по своей природе. Его низкая скорость в связке с 1С чаще всего является следствием "потерянных" индексов или неоптимальных настроек планировщика запросов. Использование auto_explain и своевременная реструктуризация позволяют добиться производительности, сопоставимой с MS SQL Enterprise версий.