Почему PostgreSQL использует одно ядро CPU в 1С и действительно ли MS SQL лучше параллелит запросы?

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе с Microsoft SQL Server на PostgreSQL многие администраторы и разработчики 1С сталкиваются с ситуацией, когда производительность системы падает, а ресурсы сервера используются неэффективно. Типичная картина: мощный сервер с 16+ ядрами, выполняется тяжелая операция (например, "Закрытие месяца"), но загружено только одно ядро процессора на 100%, в то время как остальные простаивают. В этой статье мы подробно разберем, почему так происходит, развеем мифы о "неумении" PostgreSQL работать параллельно и выясним, как правильно настроить сервер для работы с 1С.

Миф о параллелизме: PostgreSQL против MS SQL

Существует распространенное заблуждение, что PostgreSQL не умеет распараллеливать выполнение одного большого запроса, в то время как MS SQL делает это "из коробки". Давайте разберемся в технических деталях. Действительно, долгое время PostgreSQL выполнял один запрос в одном потоке. Однако, начиная с версий 9.6 и 10, в PostgreSQL появился и активно развивается механизм **Parallel Query**. Это означает, что технически СУБД способна задействовать несколько ядер для выполнения операций сканирования, соединений и агрегации в рамках одного SQL-запроса. В то же время, MS SQL Server действительно славится своим агрессивным параллелизмом. Он может разбить сложный запрос на множество потоков. Но всегда ли это хорошо для системы класса 1С:Предприятие? Давайте проанализируем ситуацию глубже и посмотрим, почему на практике мы видим то, что видим.

Проблема 1: Временные таблицы и специфика 1С

Платформа 1С:Предприятие при формировании запросов к СУБД очень активно использует временные таблицы. Это основа работы большинства сложных механизмов: от проведения документов до построения отчетов. В стандартных реализациях PostgreSQL существует архитектурное ограничение (которое постепенно устраняется в новых версиях, но все еще актуально для многих инсталляций): параллельные рабочие процессы (workers) не всегда могут иметь доступ к временным таблицам, созданным в основной сессии. Если планировщик запросов PostgreSQL видит, что в запросе участвует временная таблица (а в закрытии месяца в 1С это происходит постоянно), он часто вынужден отключать параллелизм для этого конкретного запроса и выполнять его последовательно, в одном потоке. Именно поэтому вы наблюдаете загрузку только одного ядра.

Проблема 2: Проклятие "Nested Loop" и статистика

Часто причина "тормозов" и загрузки одного ядра кроется не в отсутствии параллелизма как такового, а в некорректном выборе плана запроса. Рассмотрим одну из самых болезненных проблем PostgreSQL в связке с 1С — соединение вложенными циклами, или Nested Loop. Планировщик запросов строит план выполнения на основе статистики (количества строк, распределения данных). С временными таблицами в 1С возникает следующая ситуация: 1. 1С создает временную таблицу и быстро помещает туда данные (например, 100 000 строк). 2. Сразу после этого выполняется запрос на соединение этой временной таблицы с основной таблицей базы данных. 3. PostgreSQL не успевает собрать статистику по временной таблице ("autovacuum" еще не сработал). Он "думает", что в таблице всего 1 или 0 строк. 4. Планировщик решает: "Раз таблица крошечная, я использую алгоритм Nested Loop (вложенные циклы), так как для малого объема это самый быстрый способ". 5. В реальности происходит перебор 100 000 строк в цикле по огромной таблице базы данных. Это приводит к колоссальной нагрузке на одно ядро процессора и длительному выполнению запроса. В MS SQL статистика обновляется иначе, поэтому там эта проблема встречается реже.

Решение проблемы Nested Loop

Существует несколько способов борьбы с этой ситуацией. Способ 1. Грубая настройка (не рекомендуется как постоянное решение) Можно запретить планировщику использовать вложенные циклы, изменив параметр конфигурации postgresql.conf: enable_nestloop = off Это заставит базу использовать другие алгоритмы соединений (например, Hash Join или Merge Join), что часто спасает ситуацию при тяжелых отчетах. Однако это может замедлить простые запросы, где вложенные циклы были бы идеальным решением. Способ 2. Использование расширений (Рекомендуемый) В специализированных сборках, таких как PostgresPro, используется расширение online_analyze. Оно автоматически обновляет статистику временных таблиц сразу после их изменения, не дожидаясь фоновых процессов. Это позволяет планировщику видеть реальное количество строк и строить адекватный план выполнения. Убедитесь, что это расширение включено и настроено.

Параллелизм в MS SQL: всегда ли это благо?

Вернемся к сравнению с MS SQL. Да, он умеет дробить запрос на потоки очень эффективно. Но опытные администраторы 1С знают рекомендацию самой фирмы "1С" для MS SQL Server: Устанавливать параметр MAXDOP (Max Degree of Parallelism) равным 1. Почему так? 1С — это OLTP-система (множество коротких транзакций от большого количества пользователей). Если один пользователь запустит тяжелый отчет, и MS SQL отдаст ему все 16 ядер сервера для параллельного выполнения, работа остальных пользователей встанет. Возникнут ожидания на уровне процессора (известные как CXPACKET), блокировки и таймауты. Поэтому в мире 1С параллелизм часто **принудительно отключают** даже на MS SQL. Следовательно, аргумент "на MS SQL все летало благодаря параллелизму" часто неверен. Скорее всего, там просто корректно работала статистика и план запроса был оптимальным.

Как настроить параллелизм в PostgreSQL для 1С?

Если вы все же хотите задействовать мощь многоядерного процессора для тяжелых операций (например, ночные регламентные задания, когда пользователей в базе нет), давайте рассмотрим параметры, которые за это отвечают. Настройка параллелизма — это баланс между скоростью одного запроса и стабильностью всей системы. В файле конфигурации postgresql.conf обратите внимание на следующие параметры:

  1. max_worker_processes — общее количество фоновых процессов, которые система может запустить.
  2. max_parallel_workers_per_gather — это ключевой параметр. Он определяет, сколько максимум ядер (воркеров) может быть выделено на выполнение одного запроса. Если значение равно 0, параллелизм выключен. Для экспериментов можно установить значение 2 или 4, но не ставьте слишком много.
  3. min_parallel_table_scan_size — минимальный размер таблицы, при котором планировщик вообще начнет рассматривать возможность параллельного сканирования. Учитывая размер таблиц базы данных, если они мелкие, накладные расходы на запуск процессов "съедят" всю выгоду.
  4. parallel_setup_cost и parallel_tuple_cost — параметры стоимости. Изменяя их, можно "подсказать" планировщику, что мы предпочитаем параллельные планы.

Методика безопасного тестирования настроек

Не стоит менять параметры на "боевом" сервере наугад. Рассмотрим эффективную методику подбора параметров, предложенную опытными специалистами: 1. Разверните копию вашей базы на тестовом контуре (используя мгновенные тонкие клоны баз 1С) с аналогичными характеристиками. 2. Отключите параллелизм полностью (max_parallel_workers_per_gather = 0). 3. Запустите операцию "Тестирование и Исправление" (ТиИ) или тяжелый типовой отчет/закрытие месяца. Замерьте время выполнения. 4. Включите параллелизм (например, поставьте 2 или 4 воркера). 5. Повторите замер. 6. Если время не изменилось, попробуйте уменьшить стоимость распараллеливания (параметры parallel_setup_cost). 7. Добившись ускорения на тестовых задачах, аккуратно переносите настройки на продуктив, следя за общей загрузкой CPU.

Другие причины низкой производительности

Если 1С "тормозит" после переезда на PostgreSQL, и загрузка CPU составляет лишь одно ядро, проблема может быть вовсе не в процессоре. Давайте проверим другие критические настройки: * Дисковая подсистема и fsync. Проверьте параметр synchronous_commit. Для 1С часто допускается его отключение (значение off), что дает колоссальный прирост производительности на запись, жертвуя сохранностью последних долей секунды транзакций при сбое питания. Это не влияет на целостность базы, но значительно ускоряет работу. * Память. PostgreSQL активно использует файловый кэш ОС. Убедитесь, что параметр shared_buffers настроен корректно (обычно 1/4 от RAM), а effective_cache_size соответствует доступной памяти. * Huge Pages. Если у вас Linux и много оперативной памяти, обязательно настройте Huge Pages. Это снижает накладные расходы процессора на управление памятью.

Выводы

Проблема "одного ядра" в PostgreSQL при работе с 1С — это комплекс факторов. 1. PostgreSQL **умеет** работать параллельно, но специфика временных таблиц 1С часто блокирует этот механизм. 2. В MS SQL параллелизм для 1С часто **вреден** и отключается (MAXDOP=1), чтобы избежать блокировок. 3. Реальная причина тормозов чаще кроется в неверном плане запроса (Nested Loop) из-за отсутствия статистики по временным таблицам. Используйте online_analyze или тюнинг настроек. 4. "Тормоза" после миграции часто лечатся не сменой СУБД обратно, а грамотной настройкой конфига PostgreSQL под профиль нагрузки 1С (память, диск, автовакуум). Для Astra Linux полезен сценарий python для автоматизации процессов установки PostgreSQL.

Работайте над настройкой сервера комплексно, и PostgreSQL покажет отличную производительность.

← На главную