При работе платформы 1С:Предприятие с СУБД PostgreSQL (в частности, в конфигурациях с включенным разделением данных по общему реквизиту, таких как «Бухгалтерия предприятия» ред. 2.1 или 3.0) можно столкнуться с существенным падением производительности. Подобная проблема проявляется при формировании отчетов, расчете остатков и выполнении запросов к виртуальным таблицам.
Выясним причину такого поведения и разберем практические способы оптимизации планов запросов PostgreSQL.
При использовании режима разделения данных платформа 1С добавляет поле-разделитель (например, ОбластьДанныхОсновныеДанные) первым полем во все индексы физических таблиц. При формировании SQL-запросов условие по разделителю зачастую накладывается платформой в секции WHERE, а не в условии соединения ON.
В отличие от MS SQL Server, где первичным ключом служит кластерный индекс, хранящий сами строки таблицы, в PostgreSQL B-tree индексы хранят лишь ссылки на физические страницы (heap). В результате планировщик PostgreSQL при определенных объемах данных и некорректной статистике ошибочно рассчитывает стоимость операций и выбирает последовательное сканирование всей таблицы (Seq Scan) вместо сканирования по индексу (Index Scan) или применяет неоптимальные типы соединений.
Рассмотрим по шагам основные способы решения этой проблемы.
Чтобы заставить планировщик СУБД интенсивнее использовать индексы и выстраивать оптимальные соединения таблиц, выполним настройку конфигурационного файла postgresql.conf или установим параметры на уровне сессии/базы данных.
Для проверки влияния полного сканирования таблицы на скорость выполнения запроса изменим параметр enable_seqscan. По умолчанию он включен (on). Если перевести его в состояние off, планировщик будет избегать метода Seq Scan везде, где это возможно.
SET enable_seqscan = off;
Практические тесты показывают, что отключение enable_seqscan может снизить время выполнения тяжелых запросов выборки остатков и оборотов с 2,5–3 секунд до 0,8–1 секунды.
Снижение параметра random_page_cost относительно seq_page_cost заставляет СУБД отдавать предпочтение индексным сканированиям, особенно если база данных работает на быстрых SSD/NVMe-дисках.
random_page_cost = 1.1 # по умолчанию 4.0
seq_page_cost = 1.0
В некоторых сценариях работы 1С полезно регулировать параметр enable_nestloop. Однако полностью отключать вложенные циклы на постоянной основе не рекомендуется, так как это может привести к проседанию скорости работы других быстрых точечных запросов.
Фирма «1С» выпускает специализированные сборки PostgreSQL с доработками ядра и оптимизированным планировщиком запросов под особенности запросов платформы 1С:Предприятие (начиная с версий 9.6.3-3.1C и более новых).
Проанализируем особенности обновления и совместимости сборок:
integer_datetimes = on.integer_datetimes = off.Для предотвращения неверной оценки селективности разделителей планировщиком СУБД проанализируем настройки сбора статистики и пределов свертывания соединений:
При неравномерном распределении данных по областям (разделителям) стандартного объема сбора статистики может не хватать. Повысим глубинную детализацию статистики в postgresql.conf:
default_statistics_target = 500 # по умолчанию 100
После изменения параметра обязательно выполним сбор свежей статистики командой ANALYZE.
Запросы 1С часто содержат большое количество подзапросов и соединений. Чтобы планировщик не прекращал поиск оптимального порядка соединений раньше времени, увеличим параметры join_collapse_limit и from_collapse_limit до значения 12 или 16.
Для устранения проблем производительности PostgreSQL при работе с разделителями данных в 1С рекомендуется комплексный подход: обновить СУБД до актуальной специализированной сборки от фирмы «1С», откорректировать коэффициенты стоимости операций чтения в postgresql.conf и настроить параметры планировщика для работы со сложными запросами.