Разработка и Конфигурация · 11 мин
Набор записей или менеджер записи в 1С: что быстрее на запись
Сравнение набора записей и менеджера записи в 1С по скорости записи: как устроены механизмы, когда какой вариант выбрать, примеры кода, типичные ошибки и замеры.
Вопрос «что быстрее — набор записей или менеджер записи» возникает у каждого разработчика 1С, который оптимизирует загрузку данных в регистры сведений. Короткий ответ: при записи одной строки быстрее менеджер записи (РегистрыСведений.ИмяРегистра.СоздатьМенеджерЗаписи()), при массовой записи множества строк одним пакетом быстрее набор записей с отбором и признаком Записать() без чтения. Разница определяется не «магией платформы», а количеством обращений к СУБД и объёмом передаваемых данных.
Оба механизма в итоге порождают SQL-запросы INSERT/UPDATE/DELETE к таблице регистра. Менеджер записи работает с одной физической строкой таблицы и при записи выполняет один запрос. Набор записей — это коллекция строк с общим отбором: при записи платформа сначала удаляет старые строки по отбору (если набор записывается в режиме замещения), затем вставляет новые. Понимание этой механики и есть ключ к правильному выбору.
Как устроена запись через менеджер записи
Менеджер записи регистра сведений представляет одну строку таблицы. Типовой код выглядит так:
Менеджер = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
Менеджер.Период = ТекущаяДатаСеанса();
Менеджер.Валюта = ВалютаUSD;
Менеджер.Курс = 92.5;
Менеджер.Записать(Истина);
Параметр Истина в методе Записать() означает замещение существующей записи с тем же ключом (измерения + период). Платформа выполняет один запрос к СУБД: если запись с таким ключом есть — UPDATE, если нет — INSERT. Никакого предварительного чтения данных набора не происходит, поэтому для одиночной записи это минимально возможная стоимость операции.
Проблема появляется, когда менеджер записи вызывают в цикле. Загрузка 10 000 курсов через 10 000 вызовов Записать() — это 10 000 отдельных обращений к серверу СУБД, каждое со своим сетевым и транзакционным оверхедом. На медленных соединениях и нагруженных базах такой цикл становится узким местом всей обработки.
Как устроена запись через набор записей
Набор записей — это объект РегистрыСведенийНаборЗаписей, который содержит коллекцию строк и обязательный отбор. При вызове Набор.Записать() платформа по умолчанию работает в режиме замещения: сначала удаляет из таблицы все строки, попадающие под отбор, затем вставляет строки из набора. Обе операции выполняются в рамках одной транзакции записи.
Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.ВидЦены.Установить(ВидЦены);
Для Каждого Строка Из ТаблицаЦен Цикл
Запись = Набор.Добавить();
Запись.Номенклатура = Строка.Номенклатура;
Запись.Цена = Строка.Цена;
КонецЦикла;
Набор.Записать(Истина);
Здесь важный нюанс: если перед заполнением вызвать Набор.Прочитать(), платформа дополнительно выполнит SELECT по отбору. Для сценария «загрузить и заместить» чтение не нужно — набор формируется в памяти и записывается без чтения, что экономит один запрос и исключает блокировку читаемых строк.
Что именно сравниваем: одиночная запись против пакетной
Корректное сравнение производительности возможно только в рамках одного сценария. Сравнивать «менеджер записи в цикле на 5000 итераций» с «одним набором на 5000 строк» — значит сравнивать 5000 транзакций с одной, и результат очевиден ещё до замера.
| Сценарий | Менеджер записи | Набор записей |
|---|---|---|
| Запись одной строки | 1 запрос к СУБД — оптимально | DELETE + INSERT по отбору — избыточно |
| Обновление существующей строки | Быстро, с замещением по ключу | Медленнее: удаляются все строки по отбору |
| Загрузка сотен–тысяч строк с общим отбором | N отдельных транзакций — медленно | Одна транзакция на весь пакет — быстро |
| Запись от имени документа (движения) | Не применяется | Стандартный механизм проведения |
Из таблицы видно: «что быстрее» зависит от гранулярности операции. Менеджер записи выигрывает на точечных операциях, набор — на пакетных. Универсального победителя нет.
Как выбрать действие
Практический замер: как проверить на своей базе
Теория теорией, но конкретные цифры зависят от СУБД, железа, индексов и объёма таблицы. Простейший способ получить честные данные — замер через ТекущаяУниверсальнаяДатаВМиллисекундах() на копии рабочей базы.
- 1Создайте внешнюю обработку с двумя процедурами: запись N строк через менеджер записи в цикле и через набор записей с отбором
- 2Возьмите N, близкое к реальной задаче: 100, 1000, 10000 строк
- 3Замерьте время каждого варианта через ТекущаяУниверсальнаяДатаВМиллисекундах() до и после цикла записи
- 4Повторите замер 3–5 раз и возьмите среднее, чтобы исключить влияние фоновых процессов
- 5Проверьте оба варианта на файловой и клиент-серверной базе — разница особенно заметна в клиент-серверном режиме
Типичный результат на клиент-серверной базе: на 1000 строках цикл менеджеров записи проигрывает одному набору в разы, иногда на порядок, потому что каждая итерация — отдельный круглый путь «кластер 1С → СУБД → кластер 1С». На файловой базе разрыв меньше, но тенденция сохраняется.
Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
// ... код записи ...
Длительность = ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало;
Сообщить("Время записи: " + Длительность + " мс");
Скрытые факторы, которые влияют на скорость сильнее выбора объекта
Выбор между менеджером и набором часто даёт меньший эффект, чем сопутствующие настройки. Первый фактор — индексы. Если отбор набора накладывается по неиндексированной комбинации полей, DELETE перед вставкой превращается в сканирование таблицы, и «быстрый» набор становится медленнее цикла менеджеров. Проверьте, что поля отбора входят в индекс регистра — для стандартных отборов по измерениям и периоду платформа строит индексы автоматически, для реквизитов — нет.
Второй фактор — подписки на события и обработчики ПередЗаписью/ПриЗаписи. Они срабатывают и для менеджера записи, и для набора. Тяжёлая логика в подписке умножается на число вызовов: в цикле менеджеров она выполнится N раз, для набора — один раз на весь пакет.
Третий фактор — итоги и агрегаты. Для регистров накопления запись набора с включённым пересчётом итогов может быть заметно дороже самой вставки строк. При массовых загрузках итоги иногда отключают (УстановитьИспользованиеИтогов(Ложь)) на время загрузки и включают обратно после — но это требует монопольного или согласованного доступа и аккуратности.
Типичные ошибки и ограничения
Самая частая ошибка — чтение набора перед записью там, где оно не нужно. Конструкция Прочитать(); Добавить(); Записать(); оправдана только когда к существующим строкам нужно добавить новые, не теряя старые. Если задача — полная замена данных по отбору, чтение лишнее.
Вторая ошибка — набор записей без отбора или с неполным отбором. Для периодического регистра сведений, не подчинённого регистратору, запись набора с отбором только по периоду заместит все записи за этот период по всем измерениям. Результат — потеря чужих данных, которую сложно заметить сразу.
Отдельное ограничение: менеджер записи существует только у регистров сведений. Для регистров накопления, бухгалтерии и расчёта единственный объектный способ записи — набор записей, поэтому дилемма «что быстрее» там не стоит вовсе.
Альтернативы объектной записи
Когда и набор записей недостаточно быстр (загрузка миллионов строк), переходят на прямые запросы. Встроенный язык 1С не даёт прямого INSERT, но есть обходные пути: пакетная запись через несколько наборов с разбиением по отбору, выгрузка во временную таблицу через СУБД-специфичные средства (bcp, COPY) с последующей обработкой, либо перенос загрузки на уровень SQL с последующим обновлением служебных таблиц — последний вариант требует глубокого понимания структуры базы 1С и лишается поддержки платформы.
Сравнение вариантов
Точечные операции с одной строкой. Ограничение: только регистры сведений, непригоден для массовой загрузки
Пакетная загрузка строк с общим отбором, движения документов. Ограничение: замещает все данные по отбору, нужен контроль отбора
Экстремально большие объёмы. Ограничение: обход платформы, риск рассогласования служебных данных, нет поддержки
Как проверить результат оптимизации
После замены цикла менеджеров на набор записей убедитесь, что ускорение не достигнуто ценой корректности. Сравните количество записей в регистре до и после, проверьте несколько контрольных строк по ключевым измерениям и убедитесь, что отчёты по регистру дают те же итоги.
Как проверить результат
Совпадает с ожидаемым числом загруженных строк
Записей меньше (потеря данных) или больше (дубли из-за неполного замещения)
Значения ресурсов и измерений совпадают с источником
Расхождения — ошибка в заполнении набора или в отборе
Сократилось кратно по сравнению с циклом менеджеров
Не изменилось — ищите узкое место в подписках, индексах или итогах
Не изменились
Пострадали чужие записи — отбор набора был слишком широким
FAQ
Всегда ли набор записей быстрее менеджера записи?
Нет. Для одной строки набор медленнее: он выполняет удаление по отбору плюс вставку, тогда как менеджер — один запрос. Набор выигрывает только при пакетной записи множества строк за одну транзакцию.
Нужно ли вызывать Прочитать() перед записью набора?
Только если нужно сохранить существующие строки и добавить к ним новые. При полной замене данных по отбору чтение не нужно — оно добавляет лишний запрос SELECT и увеличивает число блокировок.
Почему цикл менеджеров записи так сильно тормозит в клиент-серверном режиме?
Каждый вызов Записать() — отдельное обращение кластера 1С к СУБД со своей транзакцией. На тысячах итераций накладные расходы на сеть и управление транзакциями превышают время самой вставки данных.
Можно ли использовать менеджер записи для регистра накопления?
Нет, объект «менеджер записи» существует только у регистров сведений. Регистры накопления, бухгалтерии и расчёта изменяются исключительно через наборы записей, обычно в составе движений документа.
Как ускорить запись набора, если она всё равно медленная?
Проверьте индексы по полям отбора, отключите на время загрузки итоги регистра (для регистров накопления), упростите подписки на события записи и разбейте очень большой пакет на части по значению отбора, чтобы не держать гигантскую транзакцию.
Опасно ли писать в регистр напрямую средствами SQL?
Да. Прямая вставка обходит логику платформы: не срабатывают подписки, не обновляются служебные механизмы, возможно рассогласование данных. Такой приём оправдан только в экстремальных случаях специалистом, понимающим структуру хранения 1С, и лишается поддержки вендора.
Что важно запомнить
Менеджер записи быстрее для одиночной строки, набор записей — для пакетной загрузки с общим отбором. Не читайте набор перед полной заменой, всегда контролируйте отбор и замеряйте производительность на своей базе, а не по чужим цифрам.