Зачем использовать периодичность «Секунда» в регистре сведений, подчиненном регистратору?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

1. Влияние настройки на кластерный индекс СУБД

Главная причина кроется в физической структуре таблиц и индексов, которые платформа 1С создает на сервере баз данных (MS SQL Server, PostgreSQL и др.). Проанализируем, как меняются индексы в зависимости от выбранного режима периодичности:

  1. Режим с явной периодичностью («Секунда», «День» и др.):

    В этом случае основным кластерным индексом таблицы становится связка: Период + Измерения. Это оптимальная структура для выборки истории срезов. СУБД мгновенно находит актуальное состояние объекта без сканирования лишних колонок.

  2. Режим «По позиции регистратора»:

    Так как в одну секунду могут быть записаны движения от разных документов, платформе необходимо гарантировать уникальность каждой строки. В результате кластерный индекс перестраивается в следующую структуру: Период + Регистратор + НомерСтроки. При этом во все вспомогательные индексы по измерениям также принудительно внедряется поле ссылки на документ-регистратор.

Такое раздувание индексов ссылочными типами данных приводит к существенной деградации производительности при частом чтении и росте объемов базы данных.

2. Скорость работы виртуальных таблиц «СрезПоследних» и «СрезПервых»

Рассмотрим, как СУБД выполняет запросы к виртуальным таблицам срезов при разных вариантах настройки:

  1. При фиксированной периодичности (например, Секунда) для получения актуального значения на определенную дату СУБД выполняет простую и быструю агрегацию по MAX(Период) с использованием прямого индекса по измерениям.
  2. В режиме «По позиции регистратора» для определения того, какая запись была сделана позже внутри одной и той же секунды, СУБД вынуждена анализировать составной момент времени — дату и ссылку на документ (UUID). Результирующий SQL-запрос становится значительно сложнее, а план выполнения требует дополнительных затрат на сортировку и фильтрацию.

3. Независимость даты записи от даты документа-регистратора

Еще одно важное архитектурное различие заключается в управлении полем Период:

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

4. Как обрабатывать коллизии при проведении документов в одну секунду

Если бизнес-логика допускает одновременное проведение нескольких документов с одинаковыми ключевыми измерениями, ошибку блокировки и неуникальности можно решить следующими практическими способами:

  1. Программный сдвиг времени записи: при проведении документа проверяем наличие записей на текущую секунду и при необходимости увеличиваем значение поля Период набора записей на одну секунду вперед.
  2. Добавление дополнительного измерения: если требуется хранить параллельные состояния, в состав измерений регистра добавляют разделитель (например, строковый идентификатор операции, вид движения или уникальный ключ).
  3. Перевод регистра в независимый режим: если регистратор нужен лишь справочно, регистр делают независимым, реквизит ДокументОснование выносят в реквизиты или измерения, а удаление движений при отмене проведения реализуют программно в модуле документа через обработчики ОбработкаПроведения и ОбработкаУдаленияПроведения.

Посмотрим на пример программного контроля времени при формировании набора записей перед записью движения:


Движение = Движения.ЦеныНоменклатуры.Добавить();
Движение.Номенклатура = Выборка.Номенклатура;
Движение.Период = Дата;

// При необходимости контролируем уникальность и сдвигаем период
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	1
    |ИЗ
    |	РегистрСведений.ЦеныНоменклатуры КАК РС
    |ГДЕ
    |	РС.Период = &Период
    |	И РС.Номенклатура = &Номенклатура
    |	И РС.Регистратор <> &Регистратор";

Запрос.УстановитьПараметр("Период", Движение.Период);
Запрос.УстановитьПараметр("Номенклатура", Движение.Номенклатура);
Запрос.УстановитьПараметр("Регистратор", Ссылка);

Если Не Запрос.Выполнить().Пустой() Тогда
    // Сдвигаем период на секунду вперед во избежание коллизии
    Движение.Период = Движение.Период + 1;
КонецЕсли;

Таким образом, использование периодичности «Секунда» для подчиненного регистратору регистра сведений — это осознанный выбор разработчиков в пользу высокой производительности запросов, компактности индексов СУБД и строгого контроля логической целостности данных.

← На главную