Как влияет использование уникального штрихкода в качестве измерения регистра накопления на производительность системы?

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

В производственных и складских системах часто возникает задача поштучного учета продукции, когда каждому экземпляру присваивается собственный уникальный идентификатор или серийный номер формата Code 128. Иногда разработчики принимают решение сделать этот уникальный номер измерением регистра накопления остатков. Проанализируем, к каким последствиям для СУБД приводит такое архитектурное решение, как на самом деле работает таблица итогов при обнулении остатков и какими способами можно оптимизировать учет поштучной номенклатуры.

Внутреннее устройство таблицы итогов: будут ли накапливаться нулевые строки

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

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

Однако здесь кроется серьезная скрытая проблема — высокая кардинальность данных и механизм хранения срезов по периодам. Платформа 1С фиксирует промежуточные итоги с шагом в один месяц. Если уникальное изделие поступило на склад в одном месяце, а было отгружено через два месяца, то в таблице итогов останутся зафиксированными срезы за промежуточные месяцы. Даже когда текущий остаток обнулен, исторические записи об этом штрихкоде продолжают физически храниться в таблице итогов за прошлые периоды, увеличивая объем базы данных и фрагментируя индексы.

Ошибки при запросах к виртуальной таблице Остатки

Главный фактор резкого падения скорости отгрузки при росте базы — некорректное получение остатков в запросе. Выясним причину этой проблемы. Если разработчик передает в виртуальную таблицу Остатки параметр даты (например, ТекущаяДата() или границу момента времени документа), платформа вынуждена восстанавливать остаток. Для этого СУБД соединяет ближайший рассчитанный исторический срез таблицы итогов с дельтой из таблицы движений.

При миллионах уникальных записей такая операция приводит к полному сканированию огромных таблиц (Index Scan или Table Scan), вызывая многосекундные зависания при каждом считывании штрихкода сканером. Чтобы запрос читал исключительно компактный актуальный срез без обхода движений, параметр «Период» передавать категорически нельзя.

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ОстаткиТоваров.Номенклатура КАК Номенклатура,
    |	ОстаткиТоваров.КоличествоОстаток КАК КоличествоОстаток
    |ИЗ
    |	РегистрНакопления.ТоварыНаСкладах.Остатки(
    |			,
    |			Штрихкод = &ИскомыйШтрихкод) КАК ОстаткиТоваров";

Запрос.УстановитьПараметр("ИскомыйШтрихкод", ШтрихкодСоСканера);
РезультатЗапроса = Запрос.Выполнить();

Обратите внимание: первый параметр виртуальной таблицы оставлен пустым. Только в этом случае СУБД обращается напрямую к срезу актуальных итогов.

Тип данных для штрихкода: скрытые ловушки числа

Нередко разработчики выбирают для измерения штрихкода тип Число, полагая, что числовые индексы всегда работают быстрее строковых. Рассмотрим, почему в случае формата Code 128 это приводит к ошибкам:

  1. Потеря лидирующих нулей. Идентификаторы часто формируются по маскам фиксированной длины (например, 000458129). При записи в числовое поле нули автоматически отсекаются, в результате чего значение в регистре перестает совпадать со считанной строкой из сканера, требуя постоянных преобразований через Формат().
  2. Специфика стандарта Code 128. Данный стандарт позволяет кодировать не только цифры, но и латинские символы, а также служебные знаки. Если производственный процесс изменится, числовое поле заблокирует возможность внедрения новых символов.

Для хранения уникальных штрихкодов рекомендуется использовать тип Строка фиксированной длины, что гарантирует точное совпадение данных и сохранение ведущих нулей без снижения эффективности поиска по индексу.

Регламентные операции для поддержания быстродействия

Если система уже спроектирована с уникальным штрихкодом в измерении регистра накопления, стабильность ее работы зависит от регулярного сервисного обслуживания базы данных. Разберем по шагам необходимые операции:

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

Альтернативная архитектура: разделение количественного и поштучного учета

Хранить единичные штрихкоды в регистре накопления в долгосрочной перспективе неэффективно, так как концепция регистров накопления создана для агрегации данных («множество движений дают мало итогов»). При поштучном учете агрегации нет: на один приход всегда приходится один расход. Рассмотрим более надежный архитектурный шаблон, который решает проблему кардинальности раз и навсегда.

Разделим контур учета на две составляющие:

  1. Количественный регистр накопления: измерениями выступают только Номенклатура и Склад. В таком регистре для 12–15 номенклатурных позиций таблица итогов будет содержать всего несколько десятков записей. Проведение документов и контроль остатков будут выполняться мгновенно.
  2. Непериодический независимый регистр сведений для поштучного учета:
    • Измерение: Штрихкод (тип Строка фиксированной длины).
    • Ресурсы / Реквизиты: Номенклатура, Склад, Статус (значения перечисления: «На складе», «Отгружен»).
    Поиск записи по штрихкоду в регистре сведений выполняется по первичному кластерному индексу за доли миллисекунды независимо от того, сколько строк хранится в таблице — 300 тысяч или 20 миллионов.

Кроме того, в случае использования регистра сведений отгруженные штрихкоды можно безболезненно переносить регламентным заданием в архивную таблицу, сохраняя рабочий объем регистра минимальным, чего невозможно сделать в стандартном регистре накопления без удаления документов-регистраторов.

← На главную