При выполнении технических операций, таких как свертка базы данных (регистров цен, остатков) или массовый импорт данных из внешних систем, перед разработчиком всегда встает дилемма: создать один огромный документ с сотнями тысяч строк или распределить эти данные по множеству небольших документов. На первый взгляд, один документ кажется более удобным для поиска, однако практика показывает, что этот путь ведет к серьезным проблемам с производительностью. Разберем детально, почему архитектурно правильнее дробить данные и каких лимитов стоит придерживаться.
Проанализируем, как платформа 1С работает с объектами типа ДокументОбъект. Когда мы вызываем метод ПолучитьОбъект() или открываем форму документа, система загружает все строки всех табличных частей в оперативную память целиком. Если в документе содержится 100 000 строк, это вызывает колоссальную нагрузку:
Рассмотрим ситуацию с точки зрения СУБД. Проведение документа — это транзакция. Пока записывается и проводится один гигантский документ, таблицы базы данных (например, таблицы движений регистров цен) могут быть заблокированы. Выясним, к чему это приводит:
Хотя технический лимит количества строк в табличной части ограничен разрядностью идентификаторов (4 байта, что позволяет хранить более 2 миллиардов записей), на практике следует придерживаться проверенных экспертных лимитов:
Посмотрим на примере, как можно реализовать алгоритм создания документов порциями. Допустим, мы обрабатываем выборку цен из регистра. Вместо того чтобы запихнуть все в один Документ.УстановкаЦенНоменклатуры, применим следующий подход:
КоличествоСтрокВПорции = 5000;
ТекущийДокумент = Неопределено;
Счетчик = 0;
Для Каждого СтрокаДанных Из ТаблицаЦен Цикл
Если Счетчик % КоличествоСтрокВПорции = 0 Тогда
// Записываем предыдущий, если он был
Если ТекущийДокумент <> Неопределено Тогда
ТекущийДокумент.Записать(РежимЗаписиДокумента.Запись);
КонецЕсли;
// Создаем новый документ
ТекущийДокумент = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
ТекущийДокумент.Дата = ДатаСвертки;
ТекущийДокумент.Комментарий = "Свертка данных (порция " + (Целое(Счетчик/КоличествоСтрокВПорции) + 1) + ")";
КонецЕсли;
НоваяСтрока = ТекущийДокумент.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДанных);
Счетчик = Счетчик + 1;
КонецЦикла;
// Не забываем записать последнюю порцию
Если ТекущийДокумент <> Неопределено Тогда
ТекущийДокумент.Записать(РежимЗаписиДокумента.Запись);
КонецЕсли;
Важный нюанс: при группировке данных старайтесь не разбивать одну и ту же номенклатуру или один и тот же склад между разными документами, если это критично для логики отчетов. Однако для регистра цен наиболее логичным будет дробление по видам цен или просто по количеству строк, так как это не влияет на итоговый срез последних.
Проанализируем аргумент в пользу одного большого документа — «так проще искать». В современных версиях 1С этот аргумент теряет силу. Работа с огромной табличной частью на форме крайне неудобна. Если нам нужно найти конкретную позицию в документе на 50 000 строк:
В случае с «кучей маленьких» документов мы можем использовать стандартный список документов с удобными фильтрами по дате, комментарию или ответственным, что в итоге оказывается эффективнее.
Подводя итог, при выполнении свертки или загрузки данных выбираем стратегию дробления. Это гарантирует:
Оптимальным признается создание документов объемом от 2 000 до 10 000 строк в зависимости от сложности логики проведения и количества реквизитов в табличной части.