Как исправить ошибку "Длина ключа индекса превышает максимально допустимую" при обновлении 1С 8.3?

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

При обновлении информационной базы 1С:Предприятие 8.3 пользователи нередко сталкиваются с критической ошибкой СУБД, связанной с превышением максимально допустимой длины ключа индекса. Эта проблема особенно актуальна при переходе с файлового режима работы базы данных на клиент-серверный вариант, например, с использованием MS SQL Server или PostgreSQL, а также при обновлении сильно доработанных конфигураций — поможет панель управления кластером серверов и сеансами 1С. Давайте подробно разберем, почему возникает эта ошибка и как ее эффективно устранить.

Типичное сообщение об ошибке выглядит следующим образом:

Ошибка СУБД:

Длина ключа индекса превышает максимально допустимую '_Referen44781_ByParentFieldFld51836_RLRSRLSSSRS (_ParentIDRRef, _Folder, _Fld51836RRef, _Description, _IDRRef, _Marked, _Fld51840, _Fld51841, _Fld51842, _Fld51843RRef, _Fld51854) UNIQUE'
по причине:
Длина ключа индекса превышает максимально допустимую '_Referen44781_ByParentFieldFld51836_RLRSRLSSSRS (_ParentIDRRef, _Folder, _Fld51836RRef, _Description, _IDRRef, _Marked, _Fld51840, _Fld51841, _Fld51842, _Fld51843RRef, _Fld51854) UNIQUE'

Эта ошибка указывает на то, что один из индексов в базе данных, который 1С пытается создать или обновить, содержит слишком много полей или поля с очень большой длиной, что превышает ограничения используемой системы управления базами данных (СУБД). Файловая версия 1С имеет более "мягкие" ограничения на длину ключей индексов, чем клиент-серверные СУБД, такие как SQL Server или PostgreSQL. Поэтому конфигурация, прекрасно работающая в файловом режиме, может столкнуться с такой проблемой при попытке ее обновления или переноса на клиент-сервер. На доступной копии базы обработка обследования метаданных поможет сопоставить физическое имя таблицы с объектом 1С и изучить его реквизиты. Сам индекс она не исправляет.

Причины возникновения ошибки "Длина ключа индекса превышает максимально допустимую"

Прежде чем перейти к решению, давайте подробнее рассмотрим основные причины этой ошибки:

  1. Использование строковых реквизитов большой длины: Наиболее частой причиной является включение в состав индекса строковых полей с большой длиной, например, Строка (500) или Строка (неограниченная длина). Каждая буква занимает определенное количество байт, и суммарная длина всех полей в индексе быстро превышает допустимый лимит.
  2. Большое количество полей в индексе: Чем больше полей включено в состав уникального или обычного индекса, тем выше вероятность превышения общей длины ключа. В клиент-серверных СУБД есть ограничения не только на суммарную длину, но и на количество ключевых столбцов (например, до 16 для MS SQL Server).
  3. Комбинация строковых и ссылочных полей: Поля ссылочных типов (например, ссылки на справочники, документы) хранятся в виде GUID, который также имеет фиксированную длину. Комбинация нескольких таких полей с длинными строковыми полями может привести к превышению лимита.
  4. Измерения регистров сведений: Измерения регистров сведений по умолчанию входят в состав уникального ключа регистра и автоматически индексируются. Если измерения включают длинные строки, это может стать причиной ошибки.

Важно понимать, что каждая СУБД имеет свои ограничения:

Пошаговое решение проблемы

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

1. Подготовка: Восстановление из архива и работа с копией

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

  2. Работайте только с копией: Никогда не выполняйте эксперименты или исправления на рабочей базе. Всегда создавайте точную копию рабочей базы и проводите все манипуляции на ней. Это позволяет безопасно проверять гипотезы, откатываться к предыдущему состоянию без риска для продуктивной работы и не "накосячить" в основной базе.

2. Поиск проблемного индекса и его объекта конфигурации

Сообщение об ошибке содержит ключевую информацию – имя проблемного индекса. В нашем примере это _Referen44781_ByParentFieldFld51836_RLRSRLSSSRS. Давайте разберем, как расшифровать это системное имя и найти соответствующий объект в конфигураторе.

  1. Анализ имени индекса:

    • _Referen: Этот префикс почти всегда указывает на объект типа "Справочник" (Reference), но может также относиться к "Документу" или "Регистру".

    • 44781: Это внутренний идентификатор (ID) объекта метаданных в конфигурации 1С. Мы будем использовать его для поиска.

    • _ByParentFieldFld51836_RLRSRLSSSRS: Эта часть указывает на поля, входящие в индекс, и их типы. Например, _ParentIDRRef – это поле, ссылающееся на родителя (ParentIDRRef), а _Fld51836RRef и _Fld51843RRef – это системные имена реквизитов, которые также являются ссылочными типами (RRef). Числа 51836, 51840, 51841, 51842, 51843, 51854 – это внутренние ID полей (реквизитов), которые участвуют в индексе.

    • UNIQUE: Этот суффикс указывает, что индекс является уникальным, то есть комбинация значений всех полей в нем должна быть неповторяющейся для каждой записи. Уникальные индексы часто создаются автоматически для измерений регистров, некоторых табличных частей или для полей, помеченных как "Основное представление".

  2. Поиск объекта в конфигураторе 1С:

    Чтобы найти, какому объекту соответствует ID 44781, мы можем воспользоваться специальными инструментами — для этого подойдут инструменты анализа метаданных и структуры системы. Откройте конфигуратор 1С.

    1. Перейдите в меню "Конфигурация" -> "Открыть конфигурацию".
    2. Затем "Конфигурация" -> "Сравнить, объединить с конфигурацией из файла..." или "Сравнить, объединить с конфигурацией базы данных..." (если у вас есть файл конфигурации или копия базы данных). В процессе сравнения вы можете увидеть внутренние идентификаторы объектов.
    3. Более удобный способ – использовать "Структуру хранения базы данных" — для этого есть анализ структуры таблиц и индексов информационной базы. Этот инструмент обычно входит в состав подсистемы "Инструменты разработчика" или "Администрирование". Если такой подсистемы нет, вы можете найти ее на диске ИТС или в интернете и добавить в свою конфигурацию. "Структура хранения базы данных" позволяет сопоставить системные имена таблиц и полей с объектами конфигурации 1С.
    4. Как вариант, можно просмотреть все справочники, документы и регистры в конфигураторе, обращая внимание на их реквизиты, особенно строковые и ссылочные, которые могут быть проиндексированы. Для поиска реквизита по ID (например, 51836) можно использовать поиск по метаданным или обработку для анализа структуры базы данных.
  3. Поиск в клиент-серверной СУБД (для продвинутых):

    Если база данных клиент-серверная (например, MS SQL Server), вы можете выполнить SQL-запросы к системным представлениям для получения информации об индексах — в этом поможет мониторинг производительности СУБД и выявление тяжелых запросов. Например, в MS SQL Server, мы можем использовать следующие запросы:

    
    SELECT
        i.name AS IndexName,
        OBJECT_NAME(i.object_id) AS TableName,
        (SELECT SUM(COL_LENGTH(OBJECT_NAME(i.object_id), c.name))
         FROM sys.index_columns ic
         INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
         WHERE ic.object_id = i.object_id AND ic.index_id = i.index_id) AS IndexKeyLengthBytes,
        i.is_unique
    FROM sys.indexes i
    WHERE i.name = '_Referen44781_ByParentFieldFld51836_RLRSRLSSSRS';
    

    Этот запрос поможет подтвердить имя индекса, его таблицу и оценить его текущую длину. Затем вы можете запросить столбцы, входящие в индекс:

    
    SELECT
        c.name AS ColumnName,
        t.name AS DataType,
        c.max_length AS MaxLengthBytes
    FROM sys.index_columns ic
    INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
    INNER JOIN sys.types t ON c.system_type_id = t.system_type_id
    WHERE ic.object_id = OBJECT_ID('ИмяПроблемнойТаблицы') AND ic.index_id = (SELECT index_id FROM sys.indexes WHERE name = '_Referen44781_ByParentFieldFld51836_RLRSRLSSSRS');
    

    Замените 'ИмяПроблемнойТаблицы' на имя таблицы, соответствующей найденному объекту 1С. Системные таблицы 1С обычно начинаются с префиксов типа _ReferenceXXX, _DocumentXXX, _InfoRgXXX и т.д.

3. Устранение проблемы: Изменение конфигурации

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

  1. Уменьшение длины строковых реквизитов:

    Это наиболее прямолинейное и часто используемое решение. Если в проблемном индексе присутствует строковый реквизит, длина которого избыточна (например, Строка (500), хотя фактически используется не более 100 символов), мы можем уменьшить его длину.

    1. Откройте конфигуратор 1С.
    2. Перейдите к найденному объекту конфигурации (например, к справочнику, соответствующему _Referen44781).
    3. Найдите реквизиты, соответствующие внутренним ID из имени индекса (например, _Fld51836RRef, _Fld51840 и т.д.). Обычно это реквизиты, добавленные разработчиками или кастомизаторами.
    4. Откройте свойства найденного реквизита. Если это строковый тип, измените его длину на максимально необходимую, но не более того. Например, если было Строка (500), попробуйте уменьшить до Строка (100) или Строка (255). Важно при этом провести анализ фактического использования данных, чтобы не обрезать важную информацию. Если вы не уверены, лучше сделать минимально возможное изменение, которое позволит пройти обновление, а затем оценить последствия.
    5. Если реквизит является ссылочным, и при этом он включен в индекс, но его присутствие в уникальном ключе не критично, возможно, стоит рассмотреть другие подходы, так как длина GUID фиксирована.
  2. Снятие индексации с реквизита (если это возможно):

    В некоторых случаях, если индексация проблемного поля не является критичной для производительности запросов или логики работы системы (например, это поле редко используется для поиска или сортировки), мы можем отключить индексацию для этого реквизита. Однако, будьте осторожны: снятие индексации может повлиять на производительность системы.

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

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

  4. Обновление платформы 1С:

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

4. Повторное обновление базы

После внесения необходимых изменений в конфигурацию:

  1. Сохраните изменения: В конфигураторе сохраните конфигурацию базы данных (меню "Конфигурация" -> "Обновить конфигурацию базы данных").

  2. Повторите процесс обновления: Попробуйте снова запустить процесс обновления на вашей копии базы данных.

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

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

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

← На главную