Статья: 4 способа ускорить запись в регистры накопления и бухгалтерии

Любой специалист по оптимизации знает, что начинать работы по ускорению 1С нужно с самого узкого места системы.

В «1С:Предприятии 8» часто таким «бутылочным горлышком» является запись в регистры:

  • Сама по себе запись в БД – достаточно долгий процесс (относительно чтения)
  • Запись в регистры выполняется при каждом проведении и перепроведении документа
  • Зачастую документы очень объемные (с большим количеством строк)
  • Один документ может порождать движения в десятках регистров
  • При перепроведении документа запись в БД зачастую выполняется 2 раза – старые движения нужно очистить, новые записать.

Оптимизация записи в регистры может существенно ускорить систему, на проектах после оптимизации процесс записи зачастую ускорялся в разы.

В этой статье мы рассмотрим основные причины и способы оптимизации медленной записи в регистры.

Если коротко…

Основные причины медленной записи следующие:

  1. Ожидание на блокировках
  2. Ошибки при массовой модификации данных
  3. Проблемы с дисками
  4. Ошибка проектирования

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

Ожидание на блокировках

Все рассматриваемые ситуации моделируются при использовании управляемого режима блокировок.

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

Ожидания могут возникать по разным причинам, разберем некоторые из них.

Излишние блокировки по времени

Представим ситуацию: при проведении реализации транзакция заблокировала нужные ей данные на 5 минут. Хорошо это или плохо?

Это ужасно! Длительность блокировки должна быть как можно меньше. Счет должен идти на секунды.

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

Схематически такое ожидание можно представить следующим образом:

Рисунок 1. Схема ожидания на блокировке

Здесь и далее синяя стрелка означает успешно установленную блокировку, красная – ожидание на блокировке.

Иванов записывает движения, но после этого выполняется какой-то долгий код. При записи накладывается исключительная управляемая блокировка и X-блокировка СУБД. Обе блокировки будут держаться до конца транзакции. Если в это время другой пользователь обратится к заблокированным данным, он встанет в очередь и получит ожидание на блокировке.

Именно этот тип ожидания чаще всего встречается на регистрах накопления и бухгалтерии.

Чтобы избежать подобной проблемы, необходимо выполнять любые модификации данных (запись, удаление, проведение) как можно ближе к концу транзакции – для сокращения времени блокировки. Если мы быстро заблокируем данные, а потом сразу отпустим, то никто ничего не заметит, в системе не будет ожиданий и запись в регистры будет быстрой.

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

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

Эскалация блокировок

Описанная выше ситуация усугубляется, если происходит эскалация блокировок.

Допустим, необходимо записать большой объем данных в регистр. Например, провести документ с табличной частью в несколько десятков тысяч строк.

В этом случае СУБД может принять решение выполнить эскалацию блокировок. Это значит, что вместо блокирования нескольких тысяч строк в таблице СУБД заблокирует всю таблицу СУБД целиком.

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

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

Рисунок 2. Схема ожидания при эскалации блокировок

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

На управляемых блокировках также есть эскалация. В 8.2 она срабатывает при наложении более 20 000 блокировок на одно пространство, а в 8.3 – при наложении более 100 000 блокировок. Как правило, до эскалации на управляемых блокировках дело не доходит, так как раньше срабатывает эскалация на СУБД.

Не используется разделение итогов

Даже сейчас мало кто знает, что в платформе есть замечательный механизм под названием разделение итогов.

Допустим, у вас розничная торговля, где большой объем документов продажи. Документы проводятся без контроля остатков: здесь важна скорость, так как требуется обслужить как можно больше покупателей за единицу времени.

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

Если кратко, то он добавляет в таблицу итогов регистра накопления (или бухгалтерии) дополнительную колонку «Splitter» и заполняет её уникальным для текущей сессии значением, благодаря чему параллельная запись в регистр становится возможной.

Данный способ можно применять, если в документе нет контроля остатков (или любого другого чтения) по данному регистру после записи движений.

Сам механизм и все плюсы от его использования подробно описаны в данной статье: https://курсы-по-1с.рф/articles/режим-разделения-итогов/

Ошибки при массовой модификации данных

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

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

Не используется отключение итогов

На моем компьютере 1 000 документов перепровелись за 94 секунды.

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

Отключить итоги можно или через стандартную обработку управления итогами, или методом регистра УстановитьИспользованиеИтогов(Ложь).

Следует помнить, что при отключении итогов у регистра его виртуальные таблицы будут недоступны, поэтому такие операции необходимо выполнять в нерабочее время.

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

В моем случае итоги по двум регистрам включились за 3 секунды. Таким образом мы улучшили время перепроведения с 94 до 69 секунд. Возможно, такое ускорение покажется слабым, но если документов и регистров много, то разница будет очень значительной.

Не используется запись в транзакции

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

Если выполнять запись 1 000 элементов, то СУБД придется 1 000 раз открыть и закрыть транзакцию, на что, естественно, уходит какое-то время. Зная это, мы можем еще немного ускорить нашу операцию, выполнив запись 1 000 элементов в одной транзакции. Для этого просто пропишем команды НачатьТранзакцию() и ЗафиксироватьТранзакцию().

Если отключить итоги и использовать запись в одной транзакции, время перепроведения 1 000 документов сокращается до 51 секунды, плюс 3 секунды на включение итогов, общий результат – 54 секунды. В результате мы ускорили загрузку примерно на 42 % по отношению к первоначальному результату.

Если дополнительно использовать распараллеливание, то результат можно сделать еще лучше.

Проблемы с дисками

Оборудование оказывает огромное влияние на скорость записи. Если есть проблемы на аппаратном уровне, то, как бы мы ни старались добиться ускорения кодом, все равно запись будет медленной.

Сейчас программы предъявляют все более и более жесткие требования к производительности оборудования. Платформе 8.1 нужно больше ресурсов, чем версии 7.7, а платформа 8.3 более требовательна, чем 8.2. Данная тенденция будет только продолжаться, так как интерфейсы все краше и функционала все больше. Все это предъявляет повышенные требования к оборудованию и в частности к дискам.

На данный момент диски HDD теряют свои позиции, уступая место SSD. Сейчас технология твердотельных накопителей находится на таком уровне, что позволяет без проблем использовать эти диски для серверных систем. SSD действительно сильно превосходят HDD как при чтении, так и при записи.

Если планируется делать апгрейд оборудования, то рекомендуется заменить обычные диски на SSD, желательно с интерфейсом PCI-E. Такая замена очень хорошо сказывается на общей производительности.

Для того чтобы снизить нагрузку на дисковую подсистему, рекомендуется разнести файл данных и файл журнала транзакций MS SQL Server на разные физические диски. В этом случае операции чтения не будут “отвлекать” диск от операций записи. Данное действие рекомендуется выполнять независимо от того, какой тип дисков вы используете.

Более подробную информацию о дисках и диагностике их загруженности можно получить здесь: https://курсы-по-1с.рф/news/2016-10-21-optimize-1c-webinar/

Ошибка проектирования

Иногда в процессе аудита производительности встречаются ситуации, когда у клиента один регистр занимает 70 % или более от всего объема базы. Это приводит к большой нагрузке на регистр и при чтении, и при записи. Все хотят в этот регистр что-то записать и что-то прочитать, ведь там лежит большая часть данных. В результате возникают ожидания на блокировках, что негативно сказывается на производительности и в том числе сильно замедляет любую модификацию данных в регистре.

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

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

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

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

Более детально эта тема раскрыта в курсе:

И да, финалисты нашего курса имеют все шансы получить высшую степень сертификации 1С – 1С:Эксперт :)

Поддержка – до 4 месяцев. Объем курса – 35 учебных часов.

Об авторе

Автор статьи – Андрей Бурмистров

E-mail: andbkt@mail.ru

Skype: Andreynikus

VK: https://vk.com/andreynikus

Андрей Бурмистров – автор и тренер курса «Ускорение и оптимизация систем на 1С:Предприятие 8.3 и подготовка на 1С:Эксперт по технологическим вопросам»

PDF-версия статьи для участников группы ВКонтакте

Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.

Если Вы еще не вступили в нее – сделайте это сейчас, и в блоке ниже (на этой странице) появятся ссылки на скачивание материалов.


Статья в PDF-форматеСтатья в PDF-формате
Вы можете скачать эту статью в формате PDF по следующей ссылке: Ссылка доступна для зарегистрированных пользователей)

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

30 комментариев к “Статья: 4 способа ускорить запись в регистры накопления и бухгалтерии

  1. LeonidMessin22 сказал:

    “Можно значительно улучшить данное время, если отключить использование итогов у регистров, по которым проводится документ”

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

    • Андрей Бурмистров сказал:

      В описанном вами случае да, получим ошибку. Этот способ хорошо подходит когда нужно просто сделать движения, не делая при этом обращения к виртуальным таблицам.

  2. LeonidMessin22 сказал:

    “Как правило, до эскалации на управляемых блокировках дело не доходит, так как раньше срабатывает эскалация на СУБД.”
    Это как?)

    • Андрей Бурмистров сказал:

      Порог эскалации блокировок на MS SQL это 5000 записей заблокированных одной инструкцией, поэтому обычно эта эскалация срабатывает раньше.

  3. Neo111 сказал:

    Вопрос про использование SSD дисков.
    Если имеются выделенные сервера СУБД, 1С и терминал и при этом основная нагрузка наблюдается на 1С сервере и терминальных серверах, какие могут быть рекомендации по использованию SSD дисков в такой ситуации (перенос каталогов сервера 1С, профилей пользователей и пр.)?
    Насколько актуальна данная рекомендация для виртуальных машин?

    • Андрей Бурмистров сказал:

      Что значит основная нагрузка наблюдается?
      Нагрузка на именно на диски?
      Если есть очереди к диску или медленная запись/чтение, тогда посмотрите через монитор ресурсов какие именно файлы используются диском. И тогда уже эти каталоги с файлами можно будет перенести на SSD или в RAM при наличии достаточного объема памяти и ИБП.

  4. Иван Татарников сказал:

    Вопрос в другом направлении: об ускорении чтения из регистров накопления – об агрегатах:) На просторах интернета мало информации по агрегатам, по ошибкам – еще меньше.

    В конфигурации завел регистр накопления оборотов и добавил агрегаты. Если после их обновления сравнить обороты, полученные с помощью виртуальной таблицы, и обороты, полученные по самим движениям, то они отличаются. Профайлером посмотрел, что виртуальная таблица обращается к таблицам агрегатов. Оказалось, что в агрегаты при обновлении попадают не все движения. Чтобы привести таблицы агрегатов к правильному состоянию необходимо очистить их и обновить заново.

    Можно ли что-то сделать с этой проблемой?
    Платформа 1С:Предприятие 8.3 (8.3.8.2167), самописная конфигурация.

    • Андрей Бурмистров сказал:

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

  5. Михаил Госьков сказал:

    “Для того чтобы снизить нагрузку на дисковую подсистему, рекомендуется разнести файл данных и файл журнала транзакций MS SQL Server на разные физические диски.”

    Если для файловой базы на терминальном сервере выделить отдельный физический диск, производительность системы тоже повышается.

    • Андрей Бурмистров сказал:

      Файловые базы это отдельный разговор. Конечно желательно что бы база лежала на отдельном диске, но все зависит от нагрузки на этот диск. Если нагрузка маленькая, то перенос базы сильно не повлияет на скорость работы. Желательно что бы база лежала на диске SSD, тогда прирост скорости будет более значительным.

      • Михаил Госьков сказал:

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

        • Андрей Бурмистров сказал:

          Как раз профили пользователей и прочих системных данных можно оставить обычном диске. Если на SSD будет база 1С, то это даст заметное ускорение для файловой базы, а вот если перенести системные файлы на SSD, то будет ли работать быстрее от этого 1С большой вопрос. Работа ОС возможно ускорится, но вот насчет ускорения работы пользователей в 1С нет такой уверенности.

          • Михаил Госьков сказал:

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

  6. Михаил Госьков сказал:

    “Если планируется делать апгрейд оборудования, то рекомендуется заменить обычные диски на SSD, желательно с интерфейсом PCI-E.”

    Хорошие результаты дает также перенос всей базы на RAMDisk, то есть в оперативную память (конечно, если объем базы позволяет сделать это). От возможной потери данных при внезапной перезагрузке сервера предохранит обмен с “зеркальной” базой, расположенной на жестком диске.
    В таком случае требуется наращивание оперативной памяти вместо подключения диска SSD.

    • Андрей Бурмистров сказал:

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

      • Михаил Госьков сказал:

        За 2 года эксплуатации базы на RAMDisk в сочетании с “зеркалом” было около десятка внезапных отключений сервера с потерей содержимого RAMDisk, однако база 1С, благодаря “зеркалу”, осталась невредимой. Период обмена с “зеркалом” составлял 300 сек. Время ответа базы 1С на RAMDisk по сравнению с жестким диском уменьшилось от 3 до 8 раз. Лимитирующим стал системный жесткий диск.
        Кроме того, “зеркало” находится на другом сервере, поэтому в случае физической аварии рабочего сервера база 1С остается невредимой.

        • Андрей Бурмистров сказал:

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

          • Михаил Госьков сказал:

            Отдельная статья по выбору оптимальной конфигурации оборудования и структуры баз 1С была бы очень интересной и полезной. Если в ней привести сравнительную таблицу всех вариантов с оценками производительности и стоимости, это будет хорошим средством для принятия решений.

          • Михаил Госьков сказал:

            Если “Зеркальная” база может быть файловой, тогда вторая лицензия СУБД не нужна?

            • Андрей Бурмистров сказал:

              Если основная база на СУБД, то сложно себе представить такое решение.

    • Валерий сказал:

      Переносить всю базу не имеет смысла, тем более часто большая часть данных базы не используется при этом память занимает.
      Сравнимое ускорение можно получить при переносе на RAM диск только TempDB. Т.к. практически любая операция (даже запись в регистры (с итогами)) нагружает TempDB

      При этом перенос TempDB значительно безопаснее.

      • Валерий сказал:

        Но в целом нужно ждать пока MSSQL научится нативно работать с БД в памяти. Т.к. в случае с RAM диском мы получаем не эффективное использование памяти сервера т.к. данные в RAM диске так же кешируются и буферизируются в основной памяти, и к ним применяются те же способы обработки как и к данным на дисках, хотя во многих случаях можно было бы использовать более эффективные способы.

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

        • Андрей Бурмистров сказал:

          В MS SQL уже есть технология “In-memory”, но 1С ее к сожалению не поддерживает.

        • Михаил Госьков сказал:

          Получается, что выгоднее настроить кеширование вместо организации RAMdisk, но как сделать это оптимально?

          • Андрей Бурмистров сказал:

            Если вы используете СУБД, тогда кэширование там работает автоматически, не нужно ничего настраивать.

      • Михаил Госьков сказал:

        Прошу извинить, что сразу не пояснил: речь идет о переносе на RAMDisk только файловой базы небольшого размера (до 10 Гб).
        Интересно попробовать перенести на RAMDisk только вспомогательные файлы базы (журнал регистрации, индексы полнотекстового поиска и т.п.), спасибо Валерию за подсказку.

        • Андрей Бурмистров сказал:

          > Интересно попробовать перенести на RAMDisk только вспомогательные файлы базы (журнал регистрации, индексы полнотекстового поиска и т.п.)

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Мы используем файлы cookies, чтобы сделать сайт удобнее.
Продолжая просмотр сайта, Вы соглашаетесь с их использованием.
Подробнее