При первичном тестировании информационной базы 1С на PostgreSQL администраторы и разработчики часто сталкиваются с ситуацией, когда одинаковый тяжелый запрос или отчет выполняется в несколько раз медленнее, чем на MS SQL Server (например, 65 секунд против 15 секунд). Разберем причины такого поведения СУБД и рассмотрим комплекс мер по тонкой настройке конфигурации для достижения максимальной производительности.
Выделим основные факторы, которые приводят к существенной разнице во времени выполнения запросов между MS SQL и PostgreSQL:
postgresql.conf ориентирован на запуск СУБД с минимальным потреблением ресурсов практически на любом оборудовании. Без ручной настройки СУБД выделяет критически мало памяти под кэш и операции сортировки..dt оптимизатор PostgreSQL не имеет распределения данных по таблицам и индексам, из-за чего строит наихудшие планы выполнения (например, полное сканирование Seq Scan вместо индексного поиска).EXISTS, которые планировщик PostgreSQL без дополнительной оптимизации обрабатывает медленнее, чем MS SQL.Проанализируем обязательный шаг, без которого любые тесты производительности будут некорректными. Сразу после загрузки информационной базы необходимо принудительно запустить сбор статистики для всех таблиц СУБД.
Выполним сбор статистики через командную строку или консоль управления СУБД:
VACUUM FULL ANALYZE;
В дальнейшем сбор статистики и очистку устаревших версий строк должен поддерживать механизм автовакуума. Для конфигураций 1С с интенсивной записью изменим пороги срабатывания в файле postgresql.conf:
autovacuum = on
autovacuum_vacuum_scale_factor = 0.05
autovacuum_analyze_scale_factor = 0.02
autovacuum_max_workers = 4
Разберем ключевые параметры postgresql.conf, влияющие на скорость выполнения запросов и работу с памятью:
shared_buffers): Задает объем памяти, используемый PostgreSQL для кэширования данных. Рекомендуется выделять около 25% от всей физической оперативной памяти сервера (например, 8GB при общем объеме 32GB).effective_cache_size): Подсказывает планировщику, сколько памяти доступно в дисковом кэше операционной системы. Устанавливается на уровне 50–75% от общего объема ОЗУ (например, 16–24GB для сервера с 32GB).work_mem): Выделяется под каждую операцию внутри запроса. При низких значениях промежуточные данные сбрасываются во временные файлы на диск. Для 1С рекомендуется задавать диапазон от 32MB до 128MB в зависимости от сложности отчетов.temp_buffers): Платформа 1С активно использует временные таблицы в пакетных запросах. Увеличение параметра до 128MB–256MB позволяет обрабатывать их в ОЗУ без лишней нагрузки на дисковую подсистему.random_page_cost): Значение по умолчанию 4.0 рассчитано на медленные HDD. Для быстрых SSD и NVMe-накопителей параметр обязательно уменьшают до 1.1–1.5, чтобы планировщик активнее задействовал индексный доступ вместо полного сканирования.join_collapse_limit и from_collapse_limit): Для предотвращения построения неоптимальных планов в громоздких запросах 1С эти параметры устанавливают равными 8.Пример блока настроек для сервера с 32 GB ОЗУ и SSD-дисками:
shared_buffers = 8GB
effective_cache_size = 24GB
work_mem = 64MB
maintenance_work_mem = 1GB
temp_buffers = 128MB
random_page_cost = 1.2
join_collapse_limit = 8
from_collapse_limit = 8
max_locks_per_transaction = 256
Для достижения максимального быстродействия СУБД рекомендуется переносить PostgreSQL на выделенный сервер под управлением Linux. Рассмотрим базовые параметры тюнинга ядра ОС:
never:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
vm.swappiness): Установим значение в sysctl.conf на уровень 1–10, чтобы ОС не выгружала кэш СУБД на диск:
vm.swappiness = 1
vm.overcommit_memory = 2
vm.overcommit_ratio = 80
noatime, чтобы исключить постоянную запись времени доступа к файлам.Если оптимизация конфигурации выполнена, но конкретный отчет или алгоритм продолжает работать медленно, проанализируем структуру запроса в 1С:
СОЕДИНЕНИЕ. Перенесем вложенный запрос в отдельную секцию МенеджерВременныхТаблиц с обязательным созданием индексов:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток
|ПОМЕСТИТЬ ВТ_Остатки
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ТоварыНаСкладахОстатки
|
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| ЕСТЬNULL(ВТ_Остатки.Остаток, 0) КАК Остаток
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Остатки КАК ВТ_Остатки
| ПО Номенклатура.Ссылка = ВТ_Остатки.Номенклатура";
ГДЕ), обязательно указываем в секции ИНДЕКСИРОВАТЬ ПО. Без индекса СУБД выполняет полное сканирование временной таблицы.