При работе с базами данных 1С:Предприятие на платформе Microsoft SQL Server системные администраторы и разработчики часто сталкиваются с критической ошибкой: «Warning! The maximum key length is 900 bytes. For some combination of large values, the insert/update operation will fail». Эта проблема блокирует возможность записи новых данных или проведение реструктуризации информационной базы.
В данной статье мы разберем природу этого ограничения, научимся расшифровывать технические сообщения SQL Server и рассмотрим практические способы устранения ошибки, основываясь на опыте решения реальных кейсов.
Для начала проанализируем техническую сторону вопроса. В версиях MS SQL Server (до 2016 года) существует жесткое ограничение на максимальный размер ключа индекса — он не может превышать 900 байт. Начиная с SQL Server 2016, лимит для некластеризованных индексов был увеличен до 1700 байт, однако для кластеризованных индексов ограничение в 900 байт часто сохраняется.
Важно помнить, что 1С использует кодировку Unicode (UCS-2), в которой каждый символ занимает 2 байта. Это означает, что если вы решите проиндексировать строковый реквизит длиной 500 символов, SQL Server попытается создать индекс размером 1000 байт (500 * 2), что мгновенно вызовет ошибку, так как это значение превышает 900 байт.
Ситуация усложняется, если индекс является составным (включает несколько полей). Например, если в индекс входят Родитель (ссылка) и Наименование (строка 150), их суммарный вес в байтах может приблизиться к критической отметке.
Рассмотрим пример сообщения из логов: The index '_Reference45_ByParentField4819_RLSRNG' has maximum length of 1033 bytes. Нам необходимо понять, какому объекту метаданных 1С соответствует таблица _Reference45 и поле Field4819.
Проанализируем суффиксы в названии индекса:
Чтобы сопоставить имена SQL с объектами 1С, мы воспользуемся встроенной функцией ПолучитьСтруктуруХраненияБазыДанных(). Рассмотрим пример кода, который поможет нам быстро найти нужные метаданные:
// Создаем массив для анализа (можно оставить пустым для всей базы)
МассивОбъектов = Новый Массив;
ТаблицаСтруктуры = ПолучитьСтруктуруХраненияБазыДанных(МассивОбъектов, Истина);
Для Каждого Таблица Из ТаблицаСтруктуры Цикл
// Ищем нашу таблицу по имени в SQL
Если Таблица.ИмяТаблицыХранения = "_Reference45" Тогда
Сообщить("Объект метаданных: " + Таблица.Метаданные);
Для Каждого Поле Из Таблица.Поля Цикл
// Ищем конкретное поле из ошибки
Если Поле.ИмяПоляХранения = "_Fld4819" Тогда
Сообщить("Реквизит: " + Поле.ИмяПоля + " (" + Поле.Метаданные + ")");
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Выполнив этот код в обработке, мы точно узнаем, какой именно справочник и какой реквизит стали причиной конфликта. Чаще всего «виновниками» оказываются поля типа Комментарий, Штрихкод или ПолноеНаименование, для которых по ошибке была включена индексация.
Иногда ошибка возникает не при создании индекса, а при записи конкретного элемента. SQL Server позволяет создать индекс с потенциально большой длиной (выдав предупреждение), но блокирует вставку, если фактические данные превышают лимит. Выясним, какая запись в базе данных содержит слишком длинную строку.
Разберем пример запроса, который находит топ-100 самых длинных значений в поле _Fld4819 таблицы _Reference45:
SELECT TOP (100)
[_IDRRef],
[_Description],
DATALENGTH([_Fld4819]) as LengthInBytes,
[_Fld4819]
FROM [ИмяВашейБазы].[dbo].[_Reference45]
ORDER BY DATALENGTH([_Fld4819]) DESC
Функция DATALENGTH возвращает количество байт, занимаемых данными. Если вы видите значения близкие к 900 или выше — это и есть причина ошибки. По значению _IDRRef (уникальный идентификатор ссылки) или _Description (Наименование) вы сможете найти этот объект в интерфейсе 1С и сократить текст.
Проанализируем основные методы устранения ошибки в зависимости от ситуации:
Если вы обнаружили, что поле «Комментарий» или любой другой длинный текст имеет свойство Индексировать в значении «Индексировать» или «Индексировать с дополнительным упорядочиванием», необходимо изменить это значение на «Не индексировать». После этого следует обновить конфигурацию базы данных. Это самый правильный и безопасный путь.
Если для бизнес-процесса требуется хранить очень длинные тексты (более 450-500 символов), рекомендуется изменить тип реквизита на Строка неограниченной длины. В SQL Server такие поля хранятся как nvarchar(max). Платформа 1С принципиально не позволяет индексировать такие поля обычными средствами СУБД, что автоматически защищает вас от ошибки «900 байт».
Если ошибка содержит суффикс _RLSRNG, значит индекс создан механизмом защиты прав доступа. Проверьте шаблоны ограничений (RLS). Если в условиях доступа используются строковые поля большой длины, постарайтесь пересмотреть логику прав так, чтобы проверка шла по ссылочным полям (например, по Группам доступа номенклатуры или контрагентов), а не по текстовым реквизитам.
Если вам критически важно быстро искать информацию по длинным текстовым полям, не используйте обычную индексацию. Включите для этого реквизита свойство «Полнотекстовый поиск». Полнотекстовые индексы 1С хранятся отдельно от таблиц SQL Server и не имеют ограничения в 900 байт.
Подводя итог, отметим: появление ошибки «The maximum key length is 900 bytes» — это всегда сигнал о неоптимальном проектировании структуры данных. Рекомендуется придерживаться следующих правил:
Следуя этим шагам, вы не только исправите текущую ошибку, но и повысите общую производительность и стабильность вашей информационной системы на базе 1С.