Турбонаддув для 1С: Вскрываем регистры бухгалтерии и ускоряем запросы в 3 раза

17.03.26

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

Нюансы работы с регистрами бухгалтерии и накопления и оптимизация работы с ними.

Общая информация

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

 

 

Здесь внимательные заметят, что появилось поле для ввода плана счетов и корреспонденции.

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

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

 

 

Разберем сам план счетов. План счетов по сути своей это тот же справочник, только имеет несколько иные настройки для предопределенных элементов, а также имеет возможность указать ПВХ (план видов характеристик) для субконто и указать их количество (максимальное количество может составлять 50)

 

 

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

Есть простой пример, например проводка дебет Товары кредит Поставщики и мы хотим оприходовать партию. Обычная проводка и по сути должна содержать в себе разрезы на номенклатуру, партию, склад. То есть здесь будет 3 субконто, а также важно понимать что если мы укажем в качестве ресурса количество в РБ, то мы обнаружим, что со счета Поставщики идет какое-то количество. Эта аналитика будет неправильной, соответственно для этого мы добавляем признак учета Количественный, а также снимаем флаг балансовый с ресурса, чтобы можно было указать в проводке количество отдельно для счетов Дт и Кт.

Плюс-минус с тем, как настроить РБ и как определить состав признаков учета и субконто мы определились, перейдем к развороту картины на СУБД.

РБ на стороне СУБД

Всем прекрасно знакома обработка структуры конфигурации (кому нет - эта обработка предоставляет просмотреть, какие таблицы как называются на стороне СУБД при создании объектов метаданных на стороне платформы).В этой обработке и в принципе на стороне СУБД все таблицы не называются именами из конфигурации, даже поля называются по-другому. Рассмотрим, как выглядит сама таблица в СУБД.

Основная таблица

Таблица РБ на стороне СУБД имеет название по шаблону AccRg + внутренняя нумерация. Здесь отражена структура таблицы в СУБД по статье с Infostart. Здесь у нас нет ничего особенного кроме отсутствия самих субконто в основной таблице (они хранятся в отдельной).

 

 

Таблица с субконто

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

 

 

Остальные таблицы

Существуют также немаловажные остальные таблицы: Остатки, Обороты и таблицы итогов субконто.

 

   

 

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

Оптимизация

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

Перейдем для начала к более востребованным таблицам на практике - Остатки.

Ускорение получения остатков

Разберем данную задачу на примере задач от УЦ №1 фирмы 1С.

 

 

На примере УЦ ускорило данный запрос с 9 секунд в целых 3 раза, что является не десятыми секундами, а нечто большим, что является превосходным результатом.

Рассмотрим поэтапно, что оказало такое влияние.

  1. Разворачивание выражения "В"

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

...AND T.FieldName IN (

    SELECT

        T.VALUE

    FROM

        #TABLE AS T

    WHERE T.VALUE IS NOT NULL)

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

 

 

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

... Субконто1 В (&МассивНоменклатуры1) ИЛИ Субконто1 В (&МассивНоменклатуры2)

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

 

 

Соответственно у нас идет уже не выборка из таблицы, как говорил ранее, а порции из параметров коллекции.

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

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

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

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

Ускоряем запись

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

Самый базовый случай - проведение документов. Да, мы будем ускорять именно запись набора записей в РБ, и какие же моменты чаще всего тормозят систему? Ответ - довольно примитивные:

  • Ожидание на блокировках
    • Излишние блокировки по времени
    • Эскалация блокировок
    • Не используется разделение итогов
  • Ошибки при массовой модификации данных
    • Не используется отключение итогов
    • Не используется запись в транзакции
  • Проблемы с дисками
  • Ошибка проектирования

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

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

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

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

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

Вернемся к случаю выше, но представим более цивилизованную систему, а не разработку австралопитеков.

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

  1. Писала набор записей, а только потом вешала блокировку и проводила сверку
  2. Блокировала регистр по определенным измерениям и проводила сбор данных и запись

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

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

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

Что же тогда предпринимает СУБД?

СУБД радикальна, она поняла, что блокировать десятки тысяч строк это гиблое дело и компьютер скорее всего зависнет, и решает заблокировать таблицу ЦЕЛИКОМ, причем реально целиком, почему? Потому что хранить данные о десятках тысяч блокировок затратнее, чем хранить данные об 1 блокировке.

А как же тогда предотвратить экскалацию?

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

В версии платформы 8.2 эскалация происходит при достижении числа 20.000, а в версии 8.3 при достижении 100.000

А собственно, что происходило бы при эскалации на предприятии?

Один сотрудник решил провести какой-нибудь документ с многочисленными ТЧ (табличными частями) и навесил эскалацию по всем складам и номенклатуре, хотя записи исключительно по Складу №1 и №2, а другой сотрудник хотел провести маленький документ всего с одной номенклатурой и вообще по Складу №3, а получил ожидание.

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

В типовых решениях всегда есть флаг "Контролировать остатки", а если его выключить, к примеру, когда розничная продажа на очень большое количество клиентов, то без этого флага поведение будет следующее:

  1. Иванов записал продажу и заблокировал записи
  2. Сидоров пытается записать, но попал в ожидание
  3. Иванов закончил запись
  4. Сидоров записал

И это возникло без включения флага "Разделение итогов", а что он из себя то представляет?Разделение итогов - добавление Splitter в СУБД и разрешение на параллельную запись, то есть у нас добавится номер сеанса и для них будут свои итоги. Удобно, не правда ли?

По умолчанию, конечно, если замечали, то при создании объекта метаданных, у которого есть это свойство (РН или РБ), оно уже включено по умолчанию, но некоторые индивидуумы его выключают, или по мере перехода с более старых конфигураций эта галка не была включена.

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

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

Довольно частая практика, не так ли? Давайте разберем, как оптимизировать такие моменты.

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

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

А как же решить проблему?

У регистра есть метод УстановитьИспользованиеИтогов, и он может предотвратить вычисление данных для таблиц итогов при записи. То есть обычно на практике, если сравнить запись без использования метода и установки использования итогов в Ложь, может повлечь сокращение по времени в 2 раза, ну или чуть меньше, но тогда вытекает проблема, таблицы итогов будут недоступны и что тогда делать? Ответ простой, включить. Ну это вопрос несколько тривиальный. Иногда запись и расчет итогов вместе занимает меньше, чем отключение итогов, запись и включение, но зачастую второй подход минимизирует время, и расчет произойдет за несколько секунд или десятков (в случае, если уж очень много всего), и в совокупности это все равно будет быстрее в 1.5 или 2 раза, чем просто запись.

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

Предыдущий результат, конечно, хорош, но что делает то СУБД во время записи? Оно естественным образом на каждый модифицируемый объект открывает и закрывает транзакцию. И поступает вопрос, тебе удобнее, когда тебе дали выполнять одну задачу, рутинную и объемную, или когда тебя каждые 5 минут пилят с новым заданием, которое ОЧЕНЬ-ОЧЕНЬ нужно сейчас и здесь. Наверное, все-таки когда дали список и ты делаешь их поэтапно, а не дергаешься.

Здесь подход в целом такой же. Перед началом обработки данных мы должны использовать механизм транзакций. По рекомендациям ИТС обработка транзакции должна выглядеть вот так

НачатьТранзакцию()

Попытка

 

    .... обход объектов и модификация

    

    ЗафиксироватьТранзакцию()

 

Исключение

    

    Если ТранзакцияАктивна() Тогда

        ОтменитьТранзакцию()

    КонецЕсли;

    

КонецПопытки

 

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

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

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

В целом, если рассматривать аппаратный уровень, все довольно знакомы с установкой Windows на HDD c 5200 оборотом и 7200, и там, и там адище, только для 5200 это просто невыносимо долго.

Тут в целом такая же ситуация, толкать что-то кодом будет довольно без смысла, если у заказчика на предприятии стоят ящики мандаринов, а не рабочие ПК.

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

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

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

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

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

Регистры бухгалтерии Регистры накопления Оптимизация записи наборов

См. также

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

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

10.11.2025    7135    ivanov660    48    

52

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

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

18.02.2025    9335    ivanov660    39    

61

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

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

24.06.2024    11775    ivanov660    13    

64

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

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

06.06.2024    18251    Evg-Lylyk    73    

46

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

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

13.03.2024    8926    spyke    29    

54

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

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

13.03.2024    12355    vasilev2015    22    

47
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. VVladislav 17.03.26 11:48 Сейчас в теме
так, а когда будет турбо?
PowerBoy; +1 Ответить
2. 1CUnlimited 425 17.03.26 12:14 Сейчас в теме
о есть обычно на практике, если сравнить запись без использования метода и установки использования итогов в Ложь, может повлечь сокращение по времени в 2 раза, ну или чуть меньше, но тогда вытекает проблема, таблицы итогов будут недоступны и что тогда делать? Ответ простой, включить.

О каком HighLoad можно говорить при включении и отключении итогов по регистру бухгалтерии ради ускорения записи? Они на большой базе не только долго будут пересчитываться, а еще отключение будет долго делать delete (а не truncate). А если это будете делать не помесячно, получите привет от Transaction log
Есть простая вещь о которой забывают. Можно держать включенными итоги за прошлый месяц включительно, но просто выключить ТекущиеИтоги . ТекущиеИтоги не будут обновляться и это реально ускорит запись, а на расчеты остатков это сильно не повлияет.
3. SerVer1C 1059 17.03.26 12:47 Сейчас в теме
Зашел, думал, что будет реально х3 на ВСЁ, а тут голая теория...
Для отправки сообщения требуется регистрация/авторизация