При работе с большими массивами нормативно-справочной информации (НСИ), когда счет идет на миллионы записей, стандартные методы записи объектов могут оказаться слишком медленными. Запись 2 000 000 элементов без оптимизации может растянуться на десятки часов или даже дней. Разберем основные стратегии и технические приемы, которые позволят сократить это время до нескольких часов или даже минут.
Основная причина низкой скорости при записи большого объема данных — это накладные расходы на открытие и закрытие транзакций СУБД для каждого отдельного объекта. Рассмотрим, как это работает: если записывать каждый элемент отдельно, система выполняет тысячи мелких операций записи в лог транзакций SQL-сервера. Проанализируем решение этой проблемы через управление транзакциями вручную.
Оптимальным подходом считается запись данных «пачками» (порциями). Опытным путем установлено, что наиболее эффективный размер порции составляет около 1000 элементов. Если делать транзакцию слишком большой (например, 100 000 элементов), это может привести к чрезмерному разрастанию лога транзакций и блокировкам таблиц. Если слишком маленькой — не удастся нивелировать накладные расходы.
Пример программной реализации пакетной записи:
Счетчик = 0;
НачатьТранзакцию();
Для Каждого ДанныеИзИсточника Из МассивДанных Цикл
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
// Заполнение реквизитов
НовыйЭлемент.Наименование = ДанныеИзИсточника.Наименование;
НовыйЭлемент.ОбменДанными.Загрузка = Истина;
НовыйЭлемент.Записать();
Счетчик = Счетчик + 1;
Если Счетчик % 1000 = 0 Тогда
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Одним из важнейших инструментов ускорения является использование свойства ОбменДанными.Загрузка = Истина. При установке этого флага платформа 1С отключает большинство прикладных проверок в модуле объекта (события ПередЗаписью, ПриЗаписи), а также не выполняет проверку на заполнение обязательных реквизитов и контроль уникальности кодов на уровне платформы. Это позволяет значительно снизить нагрузку на процессор сервера приложений.
Для достижения максимальной производительности загрузку следует выполнять в привилегированном режиме. Это позволяет обойти проверки прав доступа (RLS), которые могут существенно замедлять каждый запрос к базе данных. Проанализируем также использование монопольного режима: если во время загрузки в базе нет других пользователей, система работает быстрее, так как минимизируются накладные расходы на управление блокировками.
Если возможности платформы 1С исчерпаны, следует обратить внимание на настройки SQL-сервера. Разберем шаги, которые помогут ускорить запись миллионов строк:
.ldf и ускоряет фиксацию транзакций.Современные серверы обладают многоядерными процессорами, и использование только одного потока для записи 2 миллионов записей нерационально. Мы можем ускорить процесс, разделив исходные данные на несколько частей и запустив несколько фоновых заданий. Например, разделив массив на 4 части и запустив их параллельно, можно получить прирост скорости в 2–3 раза (в зависимости от производительности дисковой подсистемы).
Выясним причину возможных замедлений в коде:
Соответствие (хеш-таблицу), чтобы поиск в памяти занимал доли миллисекунды.INSERT напрямую в таблицы SQL. Это самый быстрый способ, однако он требует глубокого понимания структуры таблиц 1С (включая таблицы регистраций изменений и вспомогательные таблицы) и лишает систему контроля целостности данных.Подводя итог, можно сказать, что комплексное применение транзакций по 1000 элементов, использование режима ОбменДанными.Загрузка и временное отключение полнотекстового поиска позволяют увеличить скорость записи с 10–20 до 250–500 элементов в секунду и более.