К статье
Практический материал

Администрирование · 10 мин

Как ускорить запись в регистр сведений в 1С

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

Медленная запись в регистр сведений — одна из самых частых причин «тормозов» обменов, загрузок и регламентных операций в 1С. Типичная ситуация: обработка, которая в тестовой базе отрабатывала за минуты, в рабочей базе выполняется часами, а пользователи жалуются на конфликты блокировок.

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

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

Как понять, что проблема именно в записи регистра

Прежде чем менять код, убедитесь, что узкое место — именно регистр сведений, а не запросы к другим таблицам или сеть. Самый простой способ — замер производительности через конфигуратор (Отладка → Замер производительности) на участке обработки.

Характерные признаки проблемы с записью: в замере доминируют строки Записать() и обращения к конкретной таблице регистра; время растёт линейно или хуже по мере роста объёма данных; в технологическом журнале видны события TLOCK и TDEADLOCK по таблице регистра.

Запись по одной строкеКаждая запись — отдельная транзакция

Ищите в коде цикл с МенеджерЗаписи.Записать() внутри

Ошибки конфликта блокировокПараллельные процессы пишут в одни диапазоны

Проверьте технологический журнал на события TDEADLOCK

Время растёт с ростом данныхЛишние индексы или большая таблица

Посмотрите состав индексов и число записей в регистре

Пишите наборами записей, а не по одной записи

Самая распространённая ошибка — запись через РегистрыСведений.ИмяРегистра.СоздатьМенеджерЗаписи() в цикле. Каждый вызов Записать() у менеджера записи — это отдельное обращение к СУБД: проверка существования записи, вставка или обновление, обновление индексов. На десятках тысяч записей накладные расходы становятся огромными.

Правильный подход — сформировать набор записей, заполнить его в памяти и записать одним вызовом НаборЗаписей.Записать(Истина). Если регистр независимый и нужно добавить записи без затирания существующих, набирайте порции по несколько тысяч строк и записывайте пакетами, предварительно установив отбор по измерениям порции или используя запись без замещения через Записать(Ложь) там, где это допустимо по логике.

bsl
Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Период.Установить(ТекущаяДата);
Для Каждого Строка Из ТаблицаДанных Цикл
    Запись = Набор.Добавить();
    Запись.Период = ТекущаяДата;
    Запись.Номенклатура = Строка.Номенклатура;
    Запись.Цена = Строка.Цена;
КонецЦикла;
Набор.Записать(Истина);

При очень больших объёмах (сотни тысяч записей) не пытайтесь записать всё одним набором: разбивайте данные на порции по 5–50 тысяч строк. Слишком большая транзакция раздувает журнал СУБД и удерживает блокировки дольше, что вредит параллельной работе пользователей.

Сократите число транзакций и лишних операций

Каждая запись в отдельной транзакции — это фиксация в журнале СУБД, снятие и установка блокировок. Объединение записей в одну транзакцию внутри порции сокращает эти накладные расходы в разы. Если запись идёт внутри явной транзакции загрузки документов, проверьте, не пишется ли регистр многократно при записи каждого документа — часто выгоднее накопить данные и записать один раз в конце.

Отдельно проверьте подписки на события и обработчики ПриЗаписи: нередко в них скрыты запросы к справочникам, пересчёты и даже запись других регистров. Тяжёлый обработчик, срабатывающий на каждую запись, способен замедлить процесс в десятки раз. Для массовых загрузок используйте ОбменДанными.Загрузка = Истина у набора записей — это отключает бизнес-логику обработчиков, но требует, чтобы вы сами гарантировали корректность данных.

Оптимизируйте структуру регистра и индексы

Каждый индекс ускоряет чтение, но замедляет запись: при вставке строки СУБД обновляет все индексы таблицы. Проверьте в конфигураторе свойства реквизитов регистра — флаг «Индексировать» часто проставлен «на всякий случай» у полей, по которым никто не ищет. Уберите индексацию у реквизитов, не участвующих в отборах и соединениях.

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

Для подчинённых регистратору регистров сведений помните: их записи физически хранятся с ключом по регистратору. Массовое перепроведение документов каждый раз перезаписывает движения — здесь выигрыш даёт отключение итогов связанных регистров накопления на время загрузки и пакетное проведение через ОбработкаПроведения.

Типичные ошибки
01
Запись в цикле по одной записи — накладные расходы СУБД превышают полезную работу
02
Индексация всех реквизитов подряд — каждая вставка обновляет лишние индексы
03
Обработка сотен тысяч записей одной транзакцией — раздутый журнал СУБД и длинные блокировки
04
Игнорирование подписок на события — скрытый код в ПриЗаписи выполняется на каждую строку
05
Оптимизация без замера — меняется код, а узкое место оказывается в другом месте

Снизьте конкуренцию за блокировки

В клиент-серверном режиме 1С использует управляемые блокировки. Если два процесса пишут в один регистр с пересекающимися отборами, один ждёт другого, а при невезении возникает взаимоблокировка и откат транзакции. Симптом — ошибки «Конфликт блокировок при выполнении транзакции» в журнале регистрации.

Практические меры: запускайте массовые загрузки в период минимальной активности пользователей; разделяйте параллельные потоки по непересекающимся диапазонам измерений (например, по организациям или складам); сокращайте длительность транзакций — не выполняйте внутри одной транзакции запись регистра и тяжёлые расчёты.

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

Маршрут решения

Как выбрать действие

Запись идёт по одной строке в циклеПерепишите на набор записей с пакетной записью порциями
В журнале регистрации конфликты блокировокРазнесите параллельные процессы по диапазонам измерений и сократите транзакции
Запись медленная даже в монопольном режимеПроверьте лишние индексы, состав измерений и обработчики ПриЗаписи
Тормозит только при параллельной работе пользователейПеренесите загрузку на нерабочее время и уменьшите размер порций

Используйте серверные возможности СУБД

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

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

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

Проверьте результат оптимизации

После изменений повторите замер производительности на том же объёме данных и сравните время. Хороший признак — сокращение числа обращений к СУБД пропорционально уменьшению числа вызовов Записать().

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

Контрольные точки

Как проверить результат

Число вызовов Записать() в замере
Норма

Один вызов на порцию данных

Тревожный признак

Вызов на каждую строку источника

Журнал регистрации во время загрузки
Норма

Нет ошибок конфликта блокировок

Тревожный признак

Повторяющиеся ошибки TLOCK/TDEADLOCK

Данные после записи
Норма

Количество и значения совпадают с источником

Тревожный признак

Пропущенные или задвоенные записи

Время загрузки эталонного объёма
Норма

Сократилось в разы после оптимизации

Тревожный признак

Изменилось незначительно или выросло

Итог

Что важно запомнить

Основной резерв скорости — пакетная запись наборами вместо поштучной, минимум индексов и измерений, короткие транзакции и разнесение конкурирующих процессов. Сначала замерьте, потом меняйте — и проверяйте результат на эталонном объёме данных.

Частые вопросы

Что быстрее: Записать(Истина) или Записать(Ложь) у набора записей?

Записать(Истина) замещает существующие записи по установленным отборам — СУБД выполняет удаление и вставку. Записать(Ложь) только добавляет и при конфликте ключей выдаст ошибку. По скорости разница обычно невелика; выбирайте режим по бизнес-логике, а не по производительности.

Помогает ли отключение итогов для регистра сведений?

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

Безопасно ли писать в регистр напрямую через SQL?

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

Какой размер порции записи выбрать?

Универсального числа нет: ориентируйтесь на диапазон от нескольких тысяч до десятков тысяч записей. Подберите опытным путём: если транзакция длится дольше десятков секунд или растут блокировки — уменьшайте порцию; если накладные расходы на фиксацию транзакций заметны в замере — увеличивайте.

Почему запись в тестовой базе быстрая, а в рабочей — медленная?

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