Опыт оптимизации 1С на PostgreSQL

20.11.23

База данных - HighLoad оптимизация

При переводе типовой конфигурации 1C ERP/УТ/КА на PostgreSQL придется вложить ресурсы в доработку и оптимизацию запросов. Расскажем, на что обратить внимание при потерях производительности и какие инструменты/подходы помогут расследовать проблемы после перехода.

Если вы думаете, что для перехода на PostgeSQL достаточно просто загрузить dt-шник из другой СУБД, и все заработает, то вы ошибаетесь – это не совсем так.

Но и излишне напрягаться из-за возможных проблем в PostgreSQL тоже не стоит. Если при переходе правильно подойти к вопросу оптимизации, вы сможете нормально работать. И с ERP на PostgreSQL работать тоже можно – вам просто нужно будет вложить «немного» ресурсов в доработку.

Фирма «1С», со своей стороны, тоже адаптирует ERP под работу на PostgreSQL. Мы проводили замеры, сравнивали работу старых версий ERP (2.2, 2.4) и версии 2.5. В последних версиях решено очень много вопросов и проблем – видно, что они над этим работают. И с каждым новым релизом ERP работает на PostgreSQL все лучше и лучше – у ее разработчиков сейчас вообще нет вариантов не проверять конфигурацию на PostgeSQL.

Правда, добавляются новые проблемы – но куда без этого.

 

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

  • Если у вас есть инструменты, но нет знаний и опыта – вы не сможете их применить. Например, если у вас на машине прокололось колесо и есть домкрат, но вы не знаете, как с его помощью поменять колесо – вам домкрат не поможет.

  • Если есть знания и опыт, но нет инструментов – вы тоже ничего не сможете сделать.

  • И если у вас есть инструмент и инструкция по применению (знания), но нет опыта – у вас тоже возникнут проблемы.

Инструменты, знания и опыт – это три базовые вещи, которые вы должны использовать, чтобы успешно работать. Наверное, самое простое – это инструменты, потом появляются знания, а опыт приходит со временем.

 

Инструменты

 

Начнем с инструментов для анализа работы 1С на PostgreSQL – таких инструментов немного, но они есть.

 

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

Перечисленные инструменты можно условно разбить на два класса:

  • инструменты, связанные с PostgreSQL;

  • и инструменты, тем или иным образом связанные с 1С.

Начнем с инструментов для PostgreSQL.

Когда вы начинаете работать с PostgreSQL, первым делом включите два плагина: pg_stat_statements и auto_explain.

 

Плагин pg_stat_statements собирает статистику по выполняемым запросам от вашей базы. Он позволит вам получить наиболее частые запросы и запросы, которые потребляют много данных. Также можно получить длительные запросы или те, которые активно работают с жестким диском.

Здесь есть:

  • информация о среднем времени;

  • максимальное время;

  • информация о чтении и записи на диске;

  • и самое ценное – здесь есть сам запрос. Правда, есть нюанс: поле для отображения текста запроса ограничено, а в 1С запросы обычно монстроидальные. Поэтому на первое время увеличьте его размер – вы сможете поймать хотя бы часть запроса и понять, с чем связана проблема.

Плагин pg_stat_statements позволяет сортировать список обращений к базе данных:

  • по длительности;

  • по количеству повторяемых запросов;

  • и так далее.

Таким образом мы можем получать в топах самые проблемные запросы и анализировать их на необходимость оптимизации.

Второй плагин auto_explain – ключевой. Он важен, потому что дает основную информацию для оптимизации:

  • время планирования запроса;

  • текст запроса SQL – по тексту запроса SQL вы можете понять, что вообще 1С здесь запрашивает, найти этот запрос в конфигурации и оптимизировать;

  • и последний, третий пункт – это план запроса, который вам покажет, что идет не так (если вы умеете читать планы запросов). В коде 1С не всегда понятно, почему он плохо работает, а план запроса помогает увидеть, в чем проблема – заглянуть в «черный ящик» или «под капот» нашей системы.

При работе с сырым текстом запроса есть особенность:

В конфигурации 1С у вас запрос содержит классные человекопонятные названия. Документ.ПриобретениеТоваровИУслуг, регистр ОстаткиТоваровНаСкладах.

А когда вы смотрите текст запроса из СУБД, там какая-то китайская белиберда.

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

Поэтому мы написали специальный конвертер текста SQL в представления 1С. Он значительно помогает сократить время на анализ планов запросов.

Там ничего сложного нет – я его написал практически за 4 часа на коленке. Просто разбил слова по пробелам, нашел совпадающие и заменил, чтобы в результате преобразования у нас получился читаемый запрос. В некоторых случаях вы даже сможете выполнить полученный запрос в 1C.

Важный момент:

  • Конвертер позволяет преобразовывать как текст запроса SQL – вы можете его преобразовать, увидеть там обращение к таблице документа ЗаказКлиента и пойти искать, где такое встречается.

  • И также конвертер может работать с планами запросов – их тоже преобразует.

Раз уж мы заговорили про план запросов, расскажу про классный ресурс https://explain.tensor.ru/ – ничего подобного для MS SQL я за все время работы не нашел.

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

Если вы хотите научиться качественно оптимизировать, учитесь читать планы запросов. Изучайте, какой оператор что значит, что происходит с данными в каждом из них: как отображается виртуальная таблица, а как – внутреннее соединение и так далее.

Теперь попробуем подойти к сбору информации со стороны 1С.

1С тоже предоставляет мощную базу для сбора данных для анализа производительности. Только здесь перегибать палку не надо – решайте задачи поэтапно: сначала переработайте самые проблемные запросы, потом переходите к следующим и т.д.

Со стороны 1С мы используем фреймворк «Мониторинг производительности» и настройки технологического журнала – с их помощью мы получаем длительные запросы.

Без фреймворка «Мониторинг производительности» мы бы не смогли нормально провести переход с MS SQL на PostgreSQL и решить все проблемы, о которых нам писали пользователи.

Здесь мы фактически все проблемы видим заранее. Это помогает нам искать проблемы при работе на тестовых стендах, до выпуска релиза. И дальше, когда пользователь нам сообщает о проблеме, мы её ищем и находим по ней всю сопутствующую информацию:

  • имя пользователя;

  • количество строк, которые он получает;

  • длительность его запроса;

  • база, с которой он работает;

  • и самое интересное, мы получаем точку возникновения – контекст.

Например, пользователь говорит: «У меня есть проблемы». Мы получаем контекст, открываем конфигурацию, сразу находим этот запрос и можем его проанализировать. Если мы видим проблему сходу – отлично, если нет – изучаем контекст дальше.

Сейчас в работе еще один плагин – для сбора массовых запросов. Он позволит искать наиболее частые запросы и получать их контекст (на момент создания статьи этот плагин был выпущен в релиз, поэтому пользуйтесь – Поиск часто повторяющихся запросов).

 

Знания и опыт

 

Итак, мы сказали про инструменты – они вам дадут информацию о том, какие проблемы есть в базе, вернут вам набор данных для анализа.

Теперь ваша задача – проверить полученный набор данных на ошибки.

 

У фирмы «1С» на ИТС есть страница с типовыми ошибками разработчиков, где приведены варианты ошибок и способы их исправления. Мы также берем этот чек-лист и проверяем – встречаются ли эти проблемы в нашей системе.

На слайде перечислены некоторые пункты этого чек-листа – это самые частые ошибки, отсортированные по степени проблемности (по степени решаемости проблемы).

  • Первый пункт чек-листа – это обращение к свойствам объектов в полях составных типов. Не допускайте такого в ваших запросах, это очень негативно влияет на производительность.

Например, в ERP, УТ и Комплексной Автоматизации есть частоиспользуемый отчет «Расчеты с клиентами». Но, когда пользователь смотрит этот отчет, он хочет видеть информацию не только в разрезе самих заказов клиента, он хочет вытащить из заказов аналитику: договор, соглашение и так далее. Причем, даже если вы посмотрите типовой запрос, вы увидите, что разработчики сами вытягивают эти свойства в запросе прямо из реквизитов заказа.

В базовом варианте отчет обращается к одной таблице регистра «РасчетыСКлиентами», но при попытке вытащить значения свойств заказа платформа автоматически добавляет к вашему запросу еще 20-100 таблиц. Но это еще не все – если у вашего пользователя стоит ограничение по RLS, система к каждому подзапросу начинает автоматически добавлять условия. В зависимости от настроек RLS таких условий может быть очень много – в результате у вас получается монстр, который еле работает.

Эта проблема актуальна как в MS SQL, так и в PostgreSQL. Но в PostreSQL она гораздо хуже влияет на ситуацию.

В ERP версии 2.5 эта проблема решена – там разработчики внесли архитектурные изменения и добавили новый справочник, в котором хранят всю эту информацию – в результате вместо 20 таблиц обращение сжимается до двух.

  • Старайтесь в запросе отбирать только те данные, которые вам нужны. Если мы выбираем все подряд, а фильтруем только в конце – оставляем 2-3 записи, которые нам нужны – у вас выбираются данные всей кучей с учетом RLS, и это всё еле работает. По стандартам использовать условия нужно сразу – на уровне виртуальных таблиц. Не забываем также про память, ее может вдруг не хватить и тогда PostgreSQL перейдет работать на жесткий диск и у вас начнутся реальные тормоза – мы такое уже проходили.

  • Обращайте внимание на индексы – их часто не хватает. Здесь вам придется проанализировать ваши текущие потребности и самим внести необходимые изменения в конфигурацию. Кстати, фирма «1С», начиная с версии 8.3.24, обещает нам возможность наконец-то самим управлять индексами. Если это действительно так, это круто (по последним данным, эти изменения опять сдвинули – уже на 8.3.26 релиз).

  • По поводу кривой архитектуры и банальных ошибок разработчиков ничего конкретного не скажу – это очень объемная тема, и на нее просто не хватит времени. Просто старайтесь повышать квалификацию своих сотрудников и все время работайте над этим.

 

Примеры проблем и их оптимизация

 

 

Рассмотрим примеры – я надеюсь, вы ощутите всю глубину проблем, которые могут возникнуть при нарушении этих пунктов чек-листа. Мы увидим во сколько раз можно повысить производительность некоторых запросов при правильном подходе.

 

Отборы вне виртуальных таблиц

 

Запрос с отбором вне виртуальных таблиц. Разработчики часто допускают эту ошибку. Особенно когда тестируют на демонстрационных базах, где 20 или 30 документов. На такой базе невозможно ощутить и увидеть ошибку связанную с производительностью. Все будет работать очень быстро и незаметно, если не знать что искать и где смотреть.

Например, мы часто получаем в запросе цены для товаров. Но если не добавляем внутрь виртуальной таблицы условие по виду цен (это одно из трех измерений), то в большинстве случаев у нас будут проблемы.

Исправляется запрос элементарно – добавляем вид цен, и все начинает работать очень быстро и оптимально на сколько это возможно.

Теперь немного об особенностях. На MS SQL мы с этим запросом проблем не видели – он работал очень хорошо. Проблемы проявились только после перехода на PostgreSQL версии 11, потому что здесь выбор операторов зависит от количества данных.

Мы даже эксперимент проводили – до 10 тысяч записей запрос отрабатывает быстро, а больше 10 тысяч записей может 5 минут крутиться. Здорово, да?

Объясню, почему это происходит.

С помощью плагина auto_explain находим проблемный запрос, берем его текст SQL, преобразуем с помощью конвертера и идем на сайт https://explain.tensor.ru/ – он нам выводит наглядную схему запроса, с ней работать очень просто.

Когда будете работать с запросами на сайте https://explain.tensor.ru/, обращайте внимание на эти красные кружки – именно в этих местах, скорее всего, проблемы.

Если к ним подвести мышку, всплывает подсказка, и в ней мы видим:

  • время выполнения;

  • и сколько этот оператор занимает в процентах.

В данном случае отбор был произведен по двум полям – запрос прочитал порядка 140 тысяч строк и дальше их отфильтровал, осталось 30 тысяч.

А теперь посмотрите, как выглядит исправленный запрос. Здесь отбор идет по трем полям: Номенклатура, Характеристика, Вид цены – т.е. сразу отбирается уже порядка 30 тысяч записей. Этот запрос работает в 600 раз эффективнее.

В MS SQL этой проблемы нет, потому что там есть механизм Predicate Pushdown, который проталкивает эти условия дальше вниз, он автоматически фильтрует данные уже на первом участке.

 

Запрос с условием «В»

 

Следующий пример – запрос с условием «В».

Вы, наверное, читали, что есть проблема с быстродействием оператора «В». (Хочу вас обрадовать в PostgreSQL начиная с 15-й версии механизм работы с оператором «В» был переработан и теперь все работает очень хорошо)

В PostgreSQL 11 эта проблема проявляется еще сильнее. Но главная особенность этого запроса в том, что он применяется в шаблонах RLS – т.е. все операции с RLS потенциально могут работать медленно.

Исправить этот вариант можно через внутреннее соединение. Мы переписали, и запрос стал работать быстро и качественно.

Но интересный момент – на MS SQL все сразу работало хорошо и быстро.

 

А на PostgreSQL план запроса показал, что выбирается слишком много данных – СУБД для каждой записи получала по 53 строки и так делала 63 тысячи циклов. В результат общее число обработанных строк получилось в районе 3 миллионов 400 тысяч строк.

Т.е. для PostgreSQL реализация оператора «В» неудачная.

Здесь показано, как стал выглядеть план запроса в PostgreSQL, когда мы его исправили на внутреннее соединение – запрос стал работать в 10 тысяч раз быстрее исходного. Причем в MS SQL планировщик сразу строит именно такой план запроса.

Чтобы вас не огорчать, скажу, что эти скриншоты я снимал на PostgreSQL 11 версии – на ней исходный запрос выполнялся порядка 9 секунд.

Когда мы перешли на 14-ю версию PostgreSQL, исходный запрос стал выполняться 500 миллисекунд. Т.е. они оптимизировали работу из коробки. Но все равно нормальное время выполнения – порядка одной миллисекунды, а по умолчанию получается в 500 раз хуже.

 

Оператор ВЫБОР в условии динамического списка

 

Следующий момент, который тоже часто встречается – это условия в динамических списках.

Мы столкнулись с проблемой подбора назначений в одном из производственных документов. Когда пользователь нажимал в форме документа кнопку «Подобрать назначение», у него всё на 18 часов улетало. Чтобы этого избежать, приходилось подбирать назначение через Ctrl-C, Ctrl-V – из формы подбора поиск назначения просто не работал.

Когда мы это изучили, то увидели, что изначально там бралось значение через две точки. Мы оптимизировали это через реестр, и вроде стало классно работать. Это была первая итерация.

Но этот вариант работал не для всех случаев. Когда пользователь ставил отбор, форма подбора опять начинала тормозить – время открытия с 10 миллисекунд увеличивалось до нескольких секунд. Как же так? Вроде мы ставим дополнительный отбор, все должно работать лучше – почему все наоборот?

Я поясню, в чем проблема. Видите ошибку, которую я обвел? Никогда не используйте в условиях соединения оператор ВЫБОР – это приводит к значительному снижению производительности.

Когда мы использовали вариант исправления через ЕСТЬNULL, этот запрос стал «летать» во всех случаях.

Давайте посмотрим, почему такое происходит.

В плане запроса мы сразу видим красные кружки и оператор Seq Scan – это последовательное чтение данных из таблицы. Если вы видите последовательное чтение, скорее всего, здесь может быть проблема.

Чем плохо последовательное чтение? Тем, что у вас прочитываются все поля, и на них накладываются условия. Если в таблице 100 миллионов записей или 1 миллиард записей, то они будут просмотрены все. А если у нас в результате по условию подходит 1 или 2 записи, какая получается у нас эффективность? Это нехорошо. Индекс – более оптимальная вещь в данном случае.

В итоге планировщик выбрал последовательное чтение, потому что не смог подобрать необходимый индекс. А нет такого индекса от функции выбора у нас в системе. Когда мы указываем в условии: «ВЫБОР КОГДА НазначенияПереопределяемый.Заказ = Неопределено ТОГДА… ИНАЧЕ…», то у планировщика нет выбора – он не смог понять, что нужно сделать.

Когда мы исправили на ЕСТЬNULL, индекс у нас появился, и быстродействие сразу увеличилось в 1000 раз. Представляете, насколько система стала лучше работать?

 

Отборы по составному полю – особенности платформы 8.3.16

 

И последний классный пример – о том, как надо писать в фирму «1С» об ошибках.

При работе с платформой 8.3.16 мы столкнулись с особенностью, что запросы для составных типов работали неоптимально.

А с линией консультации 1С тоже надо уметь общаться – они очень любят писать в ответ: «Попробуйте другую версию», и так далее. Поэтому наберитесь терпения и попробуйте дожать вопрос, сделайте мир чуточку лучше – занесите себе плюс в карму.

 

Запрос довольно простой, наверняка у многих встречается – выборка из регистра накопления «Остатки» с отбором по какой-то временной таблице.

Этот простой запрос у нас на PostgreSQL работал очень долго – на MS SQL он отрабатывал за миллисекунды, а в PostgreSQL время выполнения достигло 25 секунд.

 

Для исправления нам пришлось типизировать заказ клиента во временной таблице через ВЫРАЗИТЬ – тогда все стало работать быстро.

В данном случае наложились друг на друга особенности PostgreSQL и поведение платформы 8.3.16, потому что каждый такой запрос сканировал весь регистр. 10 раз нажали – он 10 раз просканировал регистр. Время сканирования на каждую операцию 7 секунд, а таких операций очень много в базе.

Как выглядит оптимизированный план запроса?

Нам же не нужно сканировать все эти 2-3 миллиона записей – мы ищем одну запись, это должно быть априори быстро.

После оптимизации запрос стал работать в миллион раз лучше! А таких запросов было много, и с ними было очень неприятно работать пользователям.

 

Учитесь оптимизировать запросы – будьте в тренде

 

В качестве заключения:

  • PostgreSQL не прощает ошибки. Пишите правильно, качественно. Соблюдайте стандарты – и будет шикарно.

  • Будьте готовы в текущей ситуации потратить ресурсы на оптимизацию производительности своей системы. Конечно, это потребует времени.

  • Учитесь читать и понимать планы запросов. Если у вас еще нет таких знаний, вам сначала придется обучиться – на это может уйти до полугода. Как можно раньше начинайте готовиться.

  • Читайте, практикуйтесь, учитесь – будьте в тренде.

 

Вопросы

 

Вы рассказывали про динамический список, где пришлось избавляться от оператора ВЫБОР, а MS SQL нормально отрабатывал этот запрос?

Да. Но после оптимизации под PostgreSQL он стал еще лучше работать на MS SQL.

Любая оптимизация запроса под PostgreSQL так же благодарно воспринимается и под MS SQL. Не бывает такого, что после оптимизации под PostgreSQL запрос стал хуже выполняться на MS SQL. Нет, он будет великолепно работать и там, и там. Правильный код 1С на обеих СУБД работает хорошо. После PostgreSQL вы в любой момент можете вернуть базу на MS SQL, она будет работать только лучше.

А почему MS SQL лучше работает с запросами?

Потому что планировщик MS SQL умнее, чем планировщик PostgreSQL. Но PostgreSQL постоянно учится, развивается, есть надежда, что скоро догонит.

Вы приводили пример запроса с условием «В», который часто встречается в RLS, и говорили, что переделали его на внутреннее соединение в каком-то списке. Но RLS мы на внутреннее соединение не переделаем. Как быть?

Воспользуйтесь производительным механизмом RLS. В некоторых случаях он работает лучше, чем обычный механизм. Но есть там определенная пакость – про минусы производительного RLS я писал в статье. (Напоминаю, что наконец-то в версиях PostgreSQL с 15-й данный механизм был переработан и многие запросы стали выполняться очень хорошо. По крайней мере, те проблемные запросы, которые у нас были, в новой СУБД стали выглядеть просто отлично)

 

*************

Статья написана по итогам доклада (видео), прочитанного на конференции Infostart Event.

Вступайте в нашу телеграмм-группу Инфостарт

См. также

HighLoad оптимизация Программист 1С 8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Использование оператора «В» для полей или данных составного типа (например, Регистратор) может приводить к неочевидным проблемам.

10.11.2025    6942    ivanov660    48    

52

HighLoad оптимизация Программист 1С:Предприятие 8 1C:ERP Бесплатно (free)

Приведем примеры использования различных в динамических списках и посмотрим, почему это плохо.

18.02.2025    9234    ivanov660    39    

61

HighLoad оптимизация Технологический журнал Системный администратор Программист Бесплатно (free)

Обсудим поиск и разбор причин длительных серверных вызовов CALL, SCALL.

24.06.2024    11664    ivanov660    13    

64

HighLoad оптимизация Программист 1С:Предприятие 8 Бесплатно (free)

Метод очень медленно работает, когда параметр приемник содержит намного меньше свойств, чем источник.

06.06.2024    18114    Evg-Lylyk    73    

46

HighLoad оптимизация Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Анализ простого плана запроса. Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы.

13.03.2024    8846    spyke    29    

54

HighLoad оптимизация Программист 1С:Предприятие 8 Бесплатно (free)

Оказывается, в типовых конфигурациях 1С есть, что улучшить!

13.03.2024    12293    vasilev2015    22    

47
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Поручик 4606 20.11.23 22:57 Сейчас в теме
Спасибо. Скоро и нам этот квест проходить.
2. smit1c 107 22.11.23 14:51 Сейчас в теме
3. Cyberhawk 137 27.11.23 17:33 Сейчас в теме
пример – о том, как надо писать в фирму «1С» об ошибках
Как?
4. ivanov660 4962 28.11.23 09:31 Сейчас в теме
(3)По факту, тяжело, сложно, неудобно, но было бы здорово это делать. Если поправят, то будет счастье.
Может в далеком будущем они начнут прислушиваться и начнут более качественно взаимодействовать с разработчиками.
5. PerlAmutor 161 26.12.23 20:11 Сейчас в теме
Если RLS тормозит на MSSQL то через изменение шаблона роли я смогу через ВНУТРЕННЕЕ СОЕДИНЕНИЕ добиться хорошей скорости даже на MSSQL?
6. PerlAmutor 161 27.12.23 09:02 Сейчас в теме
Соединение через ВЫБОР КОГДА не всегда плохо. Столкнулся недавно с ситуацией, когда ВНУТРЕННЕЕ СОЕДИНЕНИЕ на MSSQL в динамическом списке приводило к Table Spool даже при соединении небольших таблиц. Операция при этом была Nested Loop. После переписывании на "ВЫБОР КОГДА" появился HASH JOIN, т.к. условие стало скалярным и запрос стал выполняться быстро даже на больших таблицах.
7. пользователь 11.06.24 17:15
Сообщение было скрыто модератором.
...
8. DrZombi 310 04.12.24 14:43 Сейчас в теме
Странно, спрашивать про MSSQL, когда тут пишут про PostgreSQL :)
Для отправки сообщения требуется регистрация/авторизация