Почему не следует задавать избыточную длину строковым реквизитам в 1С?

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

При проектировании структуры метаданных у разработчиков нередко возникает соблазн задать строковым реквизитам универсальную большую длину — например, Строка(900) или Строка(1000). На первый взгляд это кажется удобным: отпадает необходимость контролировать длину строк при выгрузке данных, сопоставлении или обрезке через СокрЛП. Однако с точки зрения архитектуры базы данных и производительности СУБД такой подход приводит к серьезным проблемам.

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

1. Особенности хранения строк в СУБД и выделение памяти

Проанализируем, как реляционные СУБД (например, Microsoft SQL Server или PostgreSQL) работают со строковыми полями различного типа:

  1. Строки переменной длины (VARCHAR / NVARCHAR): при хранении занимают фактический объем данных плюс служебные байты смещения. Однако при выполнении запросов с операциями сортировки (ORDER BY), группировки (GROUP BY) или соединений (JOIN) СУБД резервирует оперативную память под максимальный объявленный размер поля. Если в запросе участвуют сотни тысяч записей со строками по 900 символов, выделенного буфера памяти (Memory Grant) может не хватить, из-за чего промежуточные данные сбрасываются во временную базу на диск (TempDB), вызывая резкое падение производительности.
  2. Строки фиксированной длины (CHAR / NCHAR): если в свойствах реквизита установлен признак фиксированной длины, платформа 1С дополняет каждую запись пробелами справа до максимального размера. Это приводит к неоправданному росту размера таблиц, увеличению объема резервных копий и повышенной нагрузке на сеть между сервером 1С и сервером СУБД.
  3. Строки неограниченной длины (TEXT / VARCHAR(MAX)): такие поля выносятся за пределы основной страницы данных таблицы. По ним невозможно построить стандартный индекс СУБД, а в языке запросов 1С их нельзя использовать в условиях соединения и группировках без предварительного усечения функцией ПОДСТРОКА.

2. Ограничения на индексирование и размер страницы данных

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

  1. Лимит размера ключа индекса: в 1С строковые данные хранятся в двухбайтовой кодировке Unicode (UTF-16), то есть каждый символ занимает 2 байта. Строка длиной 900 символов занимает 1800 байт. В Microsoft SQL Server предельный размер ключа кластеризованного индекса равен 900 байтам, а некластеризованного — 1700 байтам. Попытка включить реквизит длиной Строка(900) в индекс приведет либо к ошибке создания индекса, либо к падению транзакции при записи строки, фактический размер которой превысит лимит.
  2. Лимит размера страницы данных: размер одной страницы в MS SQL составляет 8 КБ (8060 байт под полезные данные). Наличие нескольких широких реквизитов приводит к фрагментации таблицы и выносу строк за пределы страницы (Row-Overflow Data), что многократно увеличивает количество операций дискового ввода-вывода (I/O) при чтении каждого объекта.

3. Особенности работы функции ПОДСТРОКА в языке запросов 1С

Если реквизит имеет неограниченную длину, его использование в запросах требует обязательного применения функции ПОДСТРОКА. Выясним важную особенность поведения платформы:

Результат вычисления функции ПОДСТРОКА(Источник, Позиция, Длина) имеет строковый тип переменной длины. При этом длина результата будет считаться неограниченной, если исходное поле неограниченной длины, а параметр Длина превышает 1024 символа или не задан константой. Соответственно, при необходимости соединять таблицы по текстовым данным максимальная длина выборки не должна превышать 1024 символа.

4. Архитектурные альтернативы для сопоставления данных

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

  1. Использование хеширования: вместо поиска и соединения таблиц по длинному тексту создается отдельный индексируемый реквизит фиксированной длины для хранения контрольной суммы (например, MD5 длиной 32 символа или SHA-256). Поиск в запросах выполняется по полю хеша, что обеспечивает максимальную скорость выполнения.
    
    Хеширование = Новый ХешированиеДанных(ХешФункция.MD5);
    Хеширование.Добавить(ОчищеннаяСтрока);
    ХешСтроки = Строка(Хеширование.ХешСумма);
    
  2. Использование специализированных регистров сведений: для синхронизации номенклатуры контрагентов не следует перегружать справочник техническими реквизитами. Рекомендуется использовать непериодический регистр сведений (по аналогии с типовым механизмом сопоставления номенклатуры контрагентов), где измерениями выступают идентификаторы и очищенные наименования партнера, а ресурсом — ссылка на элемент справочника в базе.
  3. Механизм полнотекстового поиска: если сопоставление требует нечеткого поиска, учета опечаток или перестановок слов, эффективнее использовать встроенный в платформу полнотекстовый поиск, не создавая широких нестандартных полей и индексов.
← На главную