Работа с гигантскими объемами данных в 1С, такими как 4,5 миллиона позиций номенклатуры, ставит перед разработчиком ряд серьезных вызовов. Типовые механизмы конфигураций, таких как Управление торговлей 10.3, изначально не проектировались под такие нагрузки. В этой статье мы подробно разберем, как обеспечить стабильную работу системы, высокую скорость записи цен и формирование прайс-листов, используя возможности платформы 1С и MS SQL Server.
Прежде всего, выясним, реально ли это. Ответ — да, но при условии отказа от многих стандартных подходов. Проанализируем скорость записи. В лабораторных условиях (высокочастотные процессоры, NVMe-накопители) 1С способна записывать от 20 000 до 50 000 строк в секунду в регистры сведений. Однако в реальном «продакшене», где работают пользователи и включены типовые механизмы, скорость может деградировать до 3-5 позиций в секунду, если использовать стандартное проведение документов со всеми проверками.
Рассмотрим математику: 4 500 000 позиций при скорости 5 поз/сек потребуют около 250 часов непрерывной работы. Это неприемлемо. Следовательно, наша задача — максимально приблизить скорость к «сырой» записи в базу данных SQL.
Для достижения высокой производительности при массовой загрузке цен необходимо использовать следующие приемы:
ЦеныНоменклатуры, имеет смысл программно отключать итоги по этому регистру (если это не периодический регистр, требующий актуальных срезов в момент записи). Это позволяет избежать пересчета индексов при каждой транзакции.ОбменДанными.Загрузка = Истина для всех создаваемых объектов. Это отключит лишние подписки на события и проверки, которые в данном случае только тормозят процесс.Посмотрим на пример кода для записи цен напрямую в регистр сведений, минуя тяжелые документы «Установка цен номенклатуры»:
// Пример записи набором записей с оптимизацией
Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ДокументСсылка); // Если регистр подчинен регистратору
Набор.ОбменДанными.Загрузка = Истина;
// Добавляем записи в набор
Для Каждого СтрокаДанных Из ТаблицаЦен Цикл
НоваяЗапись = Набор.Добавить();
НоваяЗапись.Номенклатура = СтрокаДанных.Номенклатура;
НоваяЗапись.Цена = СтрокаДанных.Цена;
НоваяЗапись.ТипЦен = СтрокаДанных.ТипЦен;
НоваяЗапись.Период = ТекущаяДата();
КонецЦикла;
Попытка
Набор.Записать();
Исключение
Сообщить("Ошибка при записи набора: " + ОписаниеОшибки());
КонецПопытки;
Проанализируем ситуацию, характерную для магазинов автозапчастей. Часто 4,5 миллиона позиций — это прайсы поставщиков, из которых реально продаются лишь 5-10%. Загружать все эти миллионы в справочник Номенклатура — значит «убить» производительность системы. Поиск будет длиться по 30 секунд, а размер базы вырастет до сотен гигабайт.
Рекомендуемая архитектура:
Это позволит основной базе 1С оставаться легкой и быстрой, при этом предоставляя доступ ко всем 4,5 млн позиций для оценки цен и остатков.
Если мы все же решили хранить всё внутри 1С, необходимо выполнить тюнинг SQL-сервера:
Параметр Fill Factor: Установите коэффициент заполнения индексов (Fill Factor) на уровне 70-80% для таблиц регистров цен. Это создаст «запас» свободного места в страницах данных, что существенно ускорит операцию INSERT и UPDATE, уменьшая количество разбиений страниц индекса (page splits).
Модель восстановления: На время глобального обновления цен переводите базу в режим Simple (простая модель восстановления). Это предотвратит раздувание файла лога транзакций (LDF), который может мгновенно забить все дисковое пространство при записи миллионов строк.
TempDB: Поскольку 1С активно использует временные таблицы для построения прайс-листов и проведения документов, вынесите базу TempDB на самый быстрый доступный NVMe-диск. В идеале — используйте RAM-диск, если объем оперативной памяти позволяет.
Сформировать прайс-лист на 4,5 млн строк стандартным «Табличным документом» невозможно. Вы столкнетесь с ошибкой Out of Memory, так как 1С попытается построить всю модель документа в памяти. Кроме того, формат Excel ограничен 1 048 576 строками.
Разберем, как решать эту задачу:
ЗаписьТекста для формирования CSV-файла. Это позволяет выгружать данные порциями, не загружая в память весь объем.Query к SQL-таблицам. Это в разы быстрее, чем обращение через объектную модель Справочники.Номенклатура.Выбрать().
// Пример быстрого формирования CSV-файла
Запись = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8);
Запрос = Новый Запрос("ВЫБРАТЬ Код, Наименование, Цена ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СтрокаCSV = Выборка.Код + ";" + Выборка.Наименование + ";" + Выборка.Цена;
Запись.ЗаписатьСтроку(СтрокаCSV);
КонецЦикла;
Запись.Закрыть();
Выясним причину, по которой пользователи жалуются на тормоза при больших справочниках. Стандартный динамический список пытается высчитать общее количество строк и обеспечить скроллинг. На 5 млн записей это работает крайне медленно.
Что нужно сделать:
Подводя итог, можно сказать, что работа с 4,5 млн номенклатуры в 1С — это задача не столько программирования, сколько архитектурного проектирования. Использование 64-битного сервера 1С, оптимизация SQL-индексов, отказ от типовых документов в пользу прямых наборов записей и разделение данных на «оперативные» и «справочные» позволят вашей системе работать быстро даже при таких колоссальных объемах.